4
votes

The simplest way to set a background to a qml item is to just have a child rectangle whose anchors completely fill up the parent:

Item
{
    width: 320
    height: 240
    Rectangle
    {
        id: background
        anchors.fill: parent
        color: "blue"
    }

    // other items

}

However, this only works it the parent item has a size (width and height) defined.

I would like to have a container without defining a fixed size for it. The children will have fixed sizes, but as the children can change their sizes dynamically, I would like for the parent container to grow and shrink to fit.

If I anchor the children in a sequence, everything works well except for the background.

There was a question a while ago about a similar topic, but there the issue was that all the children were overlapping instead of displayed side by side. That is not my problem, because anchoring them in a sequence (or using a RowLayout) displays them correctly.

Item
{
    // I don't want a fixed size here

    Rectangle
    {
        id: background
        anchors.fill: parent
        color: "blue"
    }


    RowLayout
    {
        anchors.fill: parent

        Item
        {
            id: child1
            anchors.left = parent.left
            anchors.top: parent.top

            width:100
            height:100
        }

        Item
        {
            id: child2
            anchors.left = child1.right
            anchors.top: parent.top

            width:120
            height:120
        }

        // further children

    }

}

However, the background is not displayed because the parent doesn't have a defined size, although all the children do have a fixed size, and if I specify the right anchor of the last child to be the right of the parent, it is still displayed correctly. I guess this means that the size of the parent should be known by the renderer.

(If I use an Item or a Rectangle instead of the RowLayout, nothing changes. Actually, when using a RowLayout I could omit the sequential anchoring, but this doesn't change my problem with the background)

1
"I would like for the parent container to grow and shrink to fit." That's the description of a positioner, e.g. Column or Row. You should either size the Item according to the contained layout (see answer below) or user the aforementioned positioner types.BaCaRoZzo

1 Answers

8
votes

First of all, if you want your container to have a background, you have to make Rectangle the root instead of placing Rectangle inside Item. Also, you cannot use anchors inside a Layout since a Layout manages the layout of its children according to its own rules.

As for the question, you can use a Layout since it grows to contains all its children, like in the code as below:

Rectangle {
    anchors.centerIn: parent
    width: grid.width + 10
    height: grid.height + 10
    color: "orange"
    GridLayout {
        anchors.centerIn: parent
        id: grid
        columns: 5
        rowSpacing: 2
        columnSpacing: 2
        Repeater {
            model: 10 + Math.round(Math.random() * 50)
            Rectangle {
                width: 20 + Math.round(Math.random() * 50)
                height: 20 + Math.round(Math.random() * 50)
                border.width: 1
                border.color: "#999"
            }
        }
    }
}

Another solution is to use Item.childrenRect:

Rectangle {
    id: container
    anchors.centerIn: parent
    width: childrenRect.x + childrenRect.width;
    height: childrenRect.y + childrenRect.height;
    border.width: 1
    border.color: "#999"
    Repeater {
        model: 10 + Math.round(Math.random() * 50)
        Rectangle {
            x: Math.round(Math.random() * 500)
            y: Math.round(Math.random() * 500)
            width: 100 + Math.round(Math.random() * 100)
            height: 100 + Math.round(Math.random() * 100)
            color: Qt.rgba(Math.random(),Math.random(),Math.random(),1)
        }
    }
}