SP5RFD
SP5RFD

Reputation: 861

Rectangle does not take its parent height/width

Is it a bug or a feature?

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.2

ApplicationWindow {
    id: root
    height: 600
    width: 800

    ColumnLayout {
        id: rootLayout
        anchors.fill: parent
//        width: parent.width
//        height: parent.height

        Rectangle {
            color: "red"
            width: parent.width
            height: 200
        }
        Rectangle {
            color: "green"
            width: parent.width
            height: 200
        }
        Rectangle {
            color: "blue"
            width: parent.width
            height: 200
        }   
    }
}

This code doesn't seems to do what I need. It should open a window and draw three Rectangles in a column with width equals to parent width and height equals to 200.

It works fine, when in each Rectangle I change width and height property to a constans value (200, 300, etc.) but I want to make it relative to parent layout.

It also works when I type in Rectangle item width: root.width. So why it doesn't work when typed like in my code?

Upvotes: 1

Views: 2655

Answers (2)

Mitch
Mitch

Reputation: 24406

Use Layout.fillWidth: true:

import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.2

ApplicationWindow {
    id: root
    height: 600
    width: 800
    visible: true

    ColumnLayout {
        id: rootLayout
        anchors.fill: parent

        Rectangle {
            color: "red"
            Layout.fillWidth: true
            height: 200
        }
        Rectangle {
            color: "green"
            Layout.fillWidth: true
            height: 200
        }
        Rectangle {
            color: "blue"
            Layout.fillWidth: true
            height: 200
        }
    }
}

The Layout documentation explains its usage:

An object of type Layout is attached to children of the layout to provide layout specific information about the item. The properties of the attached object influences how the layout will arrange the items.

For instance, you can specify minimumWidth, preferredWidth, and maximumWidth if the default values are not satisfactory.

When a layout is resized, items may grow or shrink. Due to this, items have a minimum size, preferred size and a maximum size.

If minimum size have not been explicitly specified on an item, the size is set to 0. If maximum size have not been explicitly specified on an item, the size is set to Number.POSITIVE_INFINITY.

For layouts, the implicit minimum and maximum size depends on the content of the layouts.

The fillWidth and fillHeight properties can either be true or false. If it is false, the item's size will be fixed to its preferred size. Otherwise, it will grow or shrink between its minimum and maximum size as the layout is resized.

And the important note:

Note: It is not recommended to have bindings to the x, y, width, or height properties of items in a layout, since this would conflict with the goal of the Layout, and also cause binding loops.

You should probably follow this advice, and replace

height: 200

with

Layout.fillHeight: true

since your rectangles are all the same size. In this case, the rectangles will all fight for the available height, and the layout will give them equal percentages of it.


So, there are several ways to size items in a layout, but fillWidth is designed for your use case.

Upvotes: 2

Jairo
Jairo

Reputation: 886

Don't worry, is isn't a bug. Items into ColumnLayout(RowLayout and GridLayout also) has to be sized using the attached properties using Layout component. They allow us to create complex structures by setting items alignment, minimum/maximum sizes or if it should use the whole width/height. Take a look at this code, based on yours:

import QtQuick 2.5
import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1

ApplicationWindow {
    id: root
    height: 600
    width: 800

    ColumnLayout {
        id: rootLayout
        anchors.fill: parent

        Rectangle {
            color: "red"
            Layout.fillWidth: true
            height: 150
        }
        Rectangle {
            color: "green"
            Layout.preferredWidth: 400
            Layout.alignment: Qt.AlignHCenter
            height: 100
        }
        Rectangle {
            color: "blue"
            Layout.maximumWidth: 300
            Layout.preferredWidth: 400 //actual width will be 300(=maximumWidth)
            Layout.fillHeight: true
        }   
    }
}

Setting width or height to constant values seems to work too, but I would use the API proposed for these components.

I hope this help you.

Upvotes: 1

Related Questions