seemingly "simple" layout problem
-
I don’t quite understand how to anchor QML Items to one another. For example my QML includes several Items, enclosing Item subclass objects (Text, Rectangles…). In the following I have two Rectangles inside Item ‘item2’. Below that I define ‘item3’, which
ApplicationWindow { id: applicationWindow width: 1000 height: 880 visible: true title: "mbgrdview-3" Item { id: item1 Text { id: selectedFile text: "filename goes HERE" anchors.top: parent.top } Item { id: item2 anchors.top: selectedFile.bottom anchors.topMargin: 0 Rectangle { id: redRectangle width: 100 height: 100 color: "red" } Rectangle { id: blueRectangle color: "blue" anchors.top: redRectangle.bottom width: 75 height: 75 } } Item { id: item3 Rectangle { id: greenRectangle width: 50 height: 50 color: "green" } // anchor the top of this Item to the bottom of item2. // Isn't the "bottom edge" of item2 // the bottom edge of the blue rectangle? anchors.top: item2.bottom } } }
I’d expect to see three colored rectangles displayed - red, blue, and green of progressively decreasing size, arranged vertically. However what I actually get is in the - the top of the green rectangle is aligned with the top of the red rectangle - and I do not understand why. The qml defines Item item1 which contains Items item2 and item3. The red and the blue rectangle are in item2. The green rectangle is in item3, whose top is anchored to the bottom of item2 (which contains the red and blue rectangles) - so why isn’t the top of the green rectangle just below the bottom edge of the blue rectangle? Isn't the "bottom edge" of item2 the bottom edge of the blue rectangle?
I understand that I can get the three rectangles arranged in the way I expected using a simpler scheme, e.g. enclosing them in a ColumnLayout. But I’m trying to understand why the above qml doesn’t give the results I expect.
Thanks!
-
Unless you need to specifically use 'Item', why not just anchor each 'Rectangle' below the next one?
To be honest, I found your description difficult to follow, so I've taken a guess at what you're asking.
I don't know why your current code doesn't work, so I've simplified it by removing 'Item';
import QtQuick 2.12 import QtQuick.Controls 2.12 ApplicationWindow { id: applicationWindow width: 120 height: 280 visible: true title: "mbgrdview-3" Text { id: selectedFile text: "filename goes HERE" anchors.top: parent.top Rectangle { id: redRectangle color: "red" width: 100; height: width anchors.top: selectedFile.bottom } Rectangle { id: blueRectangle color: "blue" width: 75; height: width anchors.top: redRectangle.bottom } Rectangle { id: greenRectangle color: "green" width: 50; height: width anchors.top: blueRectangle.bottom } } }
Is the below image what you're expecting to see?
-
@Markkyboy - thanks - yes, the image you posted is exactly what I expected. Sorry for my complicated post. I've been assuming that Item can be used to group related items, even though Item itself is not visible; according to Qt documentation "The Item type can be useful for grouping several items under a single root visual item." . But it almost seems that Items can't act as anchors in the same way that visible items can - could that be right?
-
@Tom-asso - Yeah, that's kind of how I understood how 'Item' works.
As you've stated, you can anchor a group of objects/items inside an Item but not one to another.
We could also use Column for the same effect.
I read your description again, it makes sense, I was tired, it was late and the word 'item' kinda swamped me out, sometimes I find a picture paints a thousand words! -
Items can act as anchors and anchor themselves to other Items. Rectangle are just specialized Items.
In your case the problem was that your Items just had a
width
andheight
of 0 -
@GrecKo said in seemingly "simple" layout problem:
Items can act as anchors and anchor themselves to other Items. Rectangle are just specialized Items.
In your case the problem was that your Items just had a
width
andheight
of 0Ahhhh, got it!, I should have read the docs more closely. Thanks @GrecKo
ApplicationWindow { id: applicationWindow width: 1000 height: 880 visible: true title: "mbgrdview-3" Item { id: item1 height: 12 // text height Text { id: selectedFile text: "filename goes HERE" anchors.top: parent.top } Item { id: item2 width: 100; height: 175 // height of both rectangles anchors.top: item1.bottom Rectangle { id: redRectangle color: "red" width: 100; height: width } Rectangle { id: blueRectangle color: "blue" width: 75; height: width anchors.top: redRectangle.bottom } } Item { id: item3 width: 50; height: width anchors.top: item2.bottom Rectangle { id: greenRect color: "green" width: 50; height: width } } } }
Yep!, that works!, as does column (of course)
-
Thanks @GrecKo and @Markkyboy . I assumed that an Item automatically take the height of the tallest of its contained children - is that not the case? In my example, the red and the blue rectangles had explicit heights - do I also have to explicitly state the height of their containing Item? I didn't expect that - it means that if I want to change the height of blueRectangle to 85, then I also must explicitly change item2.height from 175 to 185? Seems qml should be able to figure that out on its own. ;-)
-
I know what you mean, there are instances where I have thought that QML should recognise and apply methods accordingly to iron out various problems, but I am also told on numerous occasions that Qt/QML is a 'declarative' programming language, meaning we must declare everything we want the program/module to execute.
I also admit to rarely using 'Item' in any of my applications so I'm somewhat unfamiliar to its usage. So, yes, it seems that you must tell 'Item' via width/height what has changed or it won't know, why this is the case is unknown to me, I guess it's just the way it is with that particular module......I'm also still very much a 'noob' when it comes to all things QML, despite fiddling with it for the last 5 or more years.