Juraj Blaho
Juraj Blaho

Reputation: 13471

Stretching element to contain all children

How is it possible in QML to automatically stretch element so that all its childs fit in it? And how to specify spacing? For example, I would like to have a rectangle around a text. The rectangle should have some internal spacing.

If I write the following then the rectangle has a size of 0,0.

Rectangle {
    color: "gray"
    anchors.centerIn: parent;

    Text {
        text: "Hello"
    }
}

If I try to fix it by using the Column element, as suggested in How to make QML items to grow to fit contents?, then I get a column through the whole window/parent,

Column {
    anchors.centerIn: parent

    Rectangle {
        color: "gray"
        anchors.fill: parent
    }

    Text {
        anchors.centerIn: parent
        text: "Hello"
    }
}

Edit:

I have also tried to use the Flow element instead of Column, but then I got a row through the whole window/parent.

Upvotes: 33

Views: 26188

Answers (3)

Alex Robenko
Alex Robenko

Reputation: 453

I don't think using chilrenRect property is sufficient (as suggested by Thorbjørn Lindeijer). It doesn't automatically take into account all various margins of the child(ren) element(s). If the latter changes, the root rectangle doesn't automatically adjust its size. I personally came with the following solution:

Rectangle {
    color: "white"
    implicitWidth: row.implicitWidth + extraLeft + extraRight
    implicitHeight: row.implicitHeight + extraTop + extraBottom
    
    property int extraMargin: row.anchors.margins ? row.anchors.margins : 0
    property int extraTop: row.anchors.topMargin ? row.anchors.topMargin : extraMargin
    property int extraBottom: row.anchors.bottomMargin ? row.anchors.bottomMargin : extraMargin
    property int extraLeft: row.anchors.leftMargin ? row.anchors.leftMargin : extraMargin
    property int extraRight: row.anchors.rightMargin ? row.anchors.rightMargin : extraMargin
    
    
    RowLayout {
        id: row
        spacing: 50
        anchors.fill:parent
        anchors.margins: 50
        anchors.leftMargin: 100
        
        Label {
            text: "hello"
        }
        Label {
            text: "world"
        }
    }
}

Upvotes: 2

Thorbjørn Lindeijer
Thorbjørn Lindeijer

Reputation: 2112

You can use the childrenRect property for this:

import QtQuick 2.0

Rectangle {
    width: 320
    height: 200

    Rectangle {
        color: "BurlyWood"
        anchors.centerIn: parent
        width: childrenRect.width + 20
        height: childrenRect.height + 20

        Text {
            id: hello
            x: 10
            y: 10
            text: "Hello"
        }

        Text {
            anchors.left: hello.right
            anchors.leftMargin: 10
            anchors.top: hello.top
            text: "World"
        }
    }
}

However, note that using childrenRect in combination with using anchors.centerIn: parent in one of the direct children yields a warning about a binding loop.

Upvotes: 52

Juraj Blaho
Juraj Blaho

Reputation: 13471

Setting the width and height manually works, but is a little ugly:

Rectangle {
    color: "gray"
    width: label.width+20
    height: label.height+20
    anchors.centerIn: parent

    Text {
        id: label
        anchors.centerIn: parent
        text: "Hello"
    }
}

Upvotes: 8

Related Questions