12
votes

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?

2
The sence of layouts is automatially pisitioning and sizing of elements. Read more here. You can use Layout.fillWidth or Layout.fillHeight to stretch an item to width or height. Or, may be set Layout.preferred{Width,Height}. Also you miss height property for ColumnLayout. - folibis
@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 for scrollbar code). - BaCaRoZzo

2 Answers

14
votes

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!

6
votes

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
    }
}