1
votes

The following QML code:

Window {
    id: window

    width: 450
    height: 700
    visible: true

    StackView {
        id: mainStack

        property Item itemTest: Item {
            id: itemTest

            ColumnLayout {
                id: mainLayout

                width: mainStack.width

                ScrollView {
                    id: scrollview

                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    clip: true
                    ScrollBar.horizontal.policy: ScrollBar.AlwaysOff

                    ColumnLayout{
                        id: colLayout
                        anchors.fill: scrollview
                    }
                }
            }
        }
        initialItem: itemTest
        anchors.fill: parent
    }
}

outputs "QML ColumnLayout: Cannot anchor to an item that isn't a parent or sibling."

Replacing "anchors.fill: scrollview" by "anchors.fill: parent" in the above code makes this message disappear but then the ColumnLayout does not seem to fill the ScrollView.

Given this behaviour, I come to the conclusion that the ScrollView in this QML file isn't actually the parent of "colLayout", which comes against my first intuition about the way parenting works in QML.

Can someone explain to me what is meant exactly by the keyword "parent" in QML ? Many thanks in advance.

1

1 Answers

2
votes

The issue is that Controls use the concept of a contentItem. While the ScrollView itself is a Control which itself is in turn an Item, the children are parented to a different Item called contentItem.

More info here:

https://doc.qt.io/qt-5/qml-qtquick-controls2-control.html#contentItem-prop

See also the comment there:

Note: Most controls use the implicit size of the content item to calculate the implicit size of the control itself. If you replace the content item with a custom one, you should also consider providing a sensible implicit size for it (unless it is an item like Text which has its own implicit size).

You don't want to grow your ColumnLayout to match the contentItem, the contentItem will automatically resize to fit the implicit size of the ColumnLayout.

If the effect you are trying to get is to match the size of the ColumnLayout to that of the ScrollView, then use something like:

                    ColumnLayout{
                        id: colLayout
                        implicitWidth: scrollview.width
                        implicitHeight: scrollview.height
                        height: implicitHeight
                        width: implicitWidth
                    }

But in that case, why bother using a ScrollView? Normally you would allow the ColumnLayout to manage its implicit size normally based on it's children. When the contentItem ends up overflowing the ScrollView, then it starts to automatically scroll.