0
votes

I'm new to Qt and QML. Examples I have seen recommend wrapping components with an Item. I want the thing the item contains to be positioned at the bottom of the application window. So, I set the item's anchor.bottom to parent.bottom. This makes the contained thing not show up. This tiny example shows the issue where the contained 'thing' is a Rectangle.

Window {
    width: 800
    height: 500
    visible: true
    title: qsTr("Test")

    Item {
        anchors {
            bottom: parent.bottom
        }

        Rectangle {
            width: 80
            height: 80
            color: "#FF0000"
        }
    }
}

I realize the item has no explicit height and its implicit height is initially 0. I believe the item's anchor is applied when the item has no height. So its bottom is its top. So its top gets set to the window bottom, effectively locating it below the window. But, the contained rectangle has a height. Does the item not dynamically size before the anchor is applied?

Is there a proper way to do this other than just deleting the Item wrapper? In my actual code, the item is not wrapping a simple rectangle. It wraps a RowLayout that contains multiple things that are not the same height. I want the RowLayout to dynamically size its height.

2
" I have seen recommend wrapping components with an Item". Where and what was the reasonning? That's not something I would recomment, quite the contrary if it is not needed like in your case.GrecKo
"Learn Qt 5" by Nicholas Sherriff is where I first came across it. But, I've seen it other places as well.Josh

2 Answers

0
votes

Wrapping components in an Item is not a general rule that should be followed everywhere. Sometimes it's helpful, but not in this case. Just getting rid of your Item should solve your problem.

Window {
    width: 800
    height: 500
    visible: true
    title: qsTr("Test")

    Rectangle {
        anchors {
            bottom: parent.bottom
        }

        width: 80
        height: 80
        color: "#FF0000"
    }
}

That should also work if your replace the Rectangle with a RowLayout.

0
votes

All you have to do is create a parent Item element that fills the whole window, then anchor your item to that.

Window {
    width: 800
    height: 500
    visible: true
    title: qsTr("Test")

    Item {
        anchors.fill: parent
        width: 100
        height: 100

        Rectangle {
            width: 80
            height: 80
            color: "#FF0000"
            /* anchor to the bottom of item */
            anchors.bottom: parent.bottom 
        }
     }
}

Why? I'm not quite sure exactly, but it sure seems to work this way.

--

If you wanted to wrap a RowLayout, you would use the same basic technique....

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Layouts 1.15
import QtQuick 2.15
 
Window {
    width: 800
    height: 500
    visible: true
    title: qsTr("Test")

    Item {
        anchors.fill: parent
        width: 100
        height: 100
        RowLayout {
            id: layout
            anchors.bottom: parent.bottom
            anchors.top: parent.verticalCenter
            spacing: 6
            Rectangle {
                 color: 'teal'
                 Layout.fillWidth: true
                 Layout.minimumWidth: 50
                 Layout.preferredWidth: 100
                 Layout.maximumWidth: 300
                 Layout.minimumHeight: 150
                 Text {
                      anchors.bottom: parent.bottom
                      text: parent.width + 'x' + parent.height
                 }
           }
            Rectangle {
                 width: 80
                 height: 80
                 color: "#FF0000"
                 
            }

            Rectangle {
                  color: 'plum'
                  Layout.fillWidth: true
                  Layout.minimumWidth: 100
                  Layout.preferredWidth: 200
                  Layout.preferredHeight: 100
                  Text {
                        anchors.bottom: parent.bottom
                        text: parent.width + 'x' + parent.height
                   }
             }
         }
     }
}