12

I am trying to create a scroll view around a ColumnLayout, unfortunately my current code doesn't work. I know about ListView, but in my case I need to create scrollable Layout, because it will contain heterogeneous elements.

ApplicationWindow {
    id: mainwindow
    title: qsTr("Hello World")
    width: 300
    height: 300
    visible: true

    ScrollView {
        anchors.fill: parent

        ColumnLayout {
            width: mainwindow.width

            Image {
                anchors.bottomMargin: 10
                source: "img/button.jpg"
                width: parent.width
                height: 400
            }

            Image {
                source: "img/button.jpg"
                width: parent.width
                height: 500
            }
        }
    }
}

This renders to this (which is clearly not what I want):

QML column layout

There are two problems:

  1. Images are not stretched across the entire window width, parent.width is ignored. I want images to have exact same width as ScrollView (no horizontal scroll)
  2. Image height property is ignored

What am I doing wrong?

Aleksei Petrenko
  • 6,698
  • 10
  • 53
  • 87
  • The sence of layouts is automatially pisitioning and sizing of elements. Read more [here](http://doc.qt.io/qt-5/qtquicklayouts-overview.html#size-constraints). You can use [Layout.fillWidth](http://doc.qt.io/qt-5/qml-qtquick-layouts-layout.html#fillWidth-attached-prop) or [Layout.fillHeight](http://doc.qt.io/qt-5/qml-qtquick-layouts-layout.html#fillHeight-attached-prop) to stretch an item to width or height. Or, may be set [Layout.preferred{Width,Height}](http://doc.qt.io/qt-5/qml-qtquick-layouts-layout.html#preferredWidth-attached-prop). Also you miss `height` property for `ColumnLayout`. – folibis Jun 05 '15 at 04:04
  • @folibis rose some nice points. You can also use `sourceSize` on the picture to force the sizing (i.e. `sourceSize.width: parent.width`). The thing is `ScrollView` is not meant to be used like that. You can either decorate a `Flickable` or switch to a `Flickable` with a custom vertical scrollbar (see [here](http://stackoverflow.com/questions/17833103/how-to-create-scrollbar-in-qtquick-2-0) for scrollbar code). – BaCaRoZzo Jun 05 '15 at 08:33

2 Answers2

16

I would go with a plain column and access the desired width property directly by id. As I understand these container elements are measuring their size depending on their content, that might be the reason why setting the ColumnLayouts width has no effect.

This works for me:

ScrollView 
{
    anchors.fill: parent

    Column {

        Repeater {
            model: 4;
            delegate: Item {
                width: root.width;
                height: image.sourceSize.height;

                Image {
                    id: image;
                    anchors.centerIn: parent;
                    width: parent.width;
                    fillMode: Image.Stretch;
                    source: "img" + (index+1) + ".png"
                }
            }
        }
    }
}

In my case root is just the parent's id. Hope this helps!

qCring
  • 1,422
  • 1
  • 15
  • 20
  • 1
    Ok, this works, thank you for help. CenterIn and Stretch are redundant BTW, it works without them. Oh... QML feels the most difficult layout engine I've ever came across. I've done XAML, android XML layouts, iOS Xib layouts and it went fine, but in QML even the simplest things seem very difficult. Is there a good step-by-step QML tutorial or book? Qt.io documentation is very sparse and scattered and really lacks good tutorials. – Aleksei Petrenko Jun 06 '15 at 01:25
  • Just now I stuck on the simplest thing in the world. I want to draw text over image but with little margin. How to do this? I tried `Image {Text {anchors.margins:10}}` and those margins don't work. – Aleksei Petrenko Jun 06 '15 at 01:27
  • 4
    After a while you'll love qml, you'll see :) Take a look at the [qml book](http://qmlbook.github.io/)! About the centered text: did you set the anchors? Also you might like [terrarium](https://github.com/penk/terrarium-app) and [livecv](https://github.com/livecv/livecv). They both offer a live qml interpreter which is great to play around with and learn how things work. – qCring Jun 06 '15 at 11:12
  • One of the few other cases in which `Column` is really useful. Nice answer! – BaCaRoZzo Jun 06 '15 at 12:51
6

Same problem on my side. This worked for me :

ScrollView {
    width: parent.width
    height : parent.height
    contentWidth: column.width    // The important part
    contentHeight: column.height  // Same
    clip : true                   // Prevent drawing column outside the scrollview borders

    Column {
        id: column
        width: parent.width

        // Your items here
    }
}
J.Jacobs
  • 703
  • 6
  • 17