0
votes

I'm trying to size a Rectangle to the size of its content:

ListView {
    anchors.fill: parent
    model: ["a", "b", "c"]
    delegate: Rectangle {
        color: "gray"
        property int margin: 20
        width: childrenRect.width + 2 * margin
        height: childrenRect.height + 2 * margin
        Text {
            text: modelData
            anchors.centerIn: parent
        }
    }
}

It seems to work visually, but the QML engine gives a lot of these errors:

qrc:/main.qml:13:19: QML Rectangle: Binding loop detected for property "width"

qrc:/main.qml:13:19: QML Rectangle: Binding loop detected for property "height"

Where is the binding loop and how to fix it?

2

2 Answers

0
votes

It is not usual to bind delegate's width to its content (childrenRect). In most cases you need parent's width and fixed (or in rare cases dynamic) height. Check out this example - I use anchorsto adjust width and fixed heightof 80:

anchors {
    left: parent.left
    right: parent.right
}
height: 80

You may also be interested in Label positioning inside this component.

0
votes

The error comes from the item Rectangle: its size is based on its content (by using childrenRect). But, your Text is placed according to the size of its parent (by using centerIn).

The position of Textis based on the size of its parent (centered in the Rectangle). childrenRect holds the collective geometry of the children (such as bounding rect property). When Rectangle is resized, the position of Text changes also. Then, the childrenRect will change too to map the new position of Text.

So, you will create a loop if you map the size of Rectangle on the children rect property and you center Text in Rectangle.

A quick example to add a background to a text centered in a list view:

ListView {
        id: list
        anchors.fill: parent
        model: ["a", "b", "c"]
        delegate: Item {
            property int margin: 20
            anchors.left: parent.left // Take all the width
            anchors.right: parent.right
            height: 40 // The height is 0 by default
            Rectangle { // Background under the text only. Will not fill the whole row
                color: "gray"
                anchors.centerIn: parent
                width: text.width 
                height: text.height
            }

            Text {
                id:  text
                text: modelData
                anchors.centerIn: parent
            }
        }
    }