Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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 attached image - 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?

    rgb-no-item.JPG



  • @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!


  • Qt Champions 2018

    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 and height 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 and height of 0

    Ahhhh, 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)

    column.JPG



  • 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. ;-)



  • @Tom-asso

    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.