How to make the Layout change when an item changes



  • Hi,
    when i change the size of an Item i would like the other to move, like if the new height (int the example) was the same at the begining. When i do this code it doesn't work. Here is a peace of code to illustrate this

    import QtQuick 2.2
    import QtQuick.Layouts 1.1
    import QtQuick.Controls 1.1

    ApplicationWindow {
    minimumHeight: 100
    maximumHeight: 300
    minimumWidth: 100
    maximumWidth: 300
    width: 300
    height: 300

    ColumnLayout {
        id: layoutC
        anchors.fill: parent // Doesn't work with that
        //width: 100 // Works with that
        onWidthChanged: console.log("Column Width : "+width)
        Rectangle {
            id: rect1
            color: "red"
            visible: true
            onWidthChanged: console.log("Rectangle 1 Width : "+width)
            Layout.fillHeight: true // Doesn't extend
            Layout.fillWidth: true // Doesn't extend
            Layout.minimumHeight: 50
            Layout.maximumHeight: 100
        }
        Rectangle {
            id: rect2
            color: "#028000"
            //width: rectangle.width
            height: 200
            onWidthChanged: console.log("Rectangle 2 Width : "+width)
            Layout.fillHeight: false // Doesn't extend
            Layout.fillWidth: true // Doesn't extend
            Layout.minimumHeight: 50
            Layout.maximumHeight: 300
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    if (rect2.height==100) {
                        rect2.height=200
                        rect3.height-=100 // Not Good i Know it is to illustrate : Remove it
                    }
                    else {
                        rect2.height=100
                        rect3.height+=100 // Not Good i Know it is to illustrate : Remove it
                    }
                    console.log("clicked")
                }
            }
        }
        Rectangle {
            id: rect3
            color: "#0500ff"
            onWidthChanged: console.log("Rectangle 3 Width : "+width)
            onHeightChanged: console.log("Rectangle 3 Height : "+height)
            Layout.fillHeight: true // Doesn't extend
            Layout.fillWidth: true // Doesn't extend
            Layout.minimumHeight: 50
            anchors.top: rect2.bottom // Remove it and you will see that
        }
    }
    

    }

    What i want is that it works the same as if the line when i put "Remove" was not there.
    Thanks
    Sincerely



  • @archqt
    Frankly, I haven't understood what you're trying to achieve. You have three rectangles: "red", "green" and "blue" inside an ApplicationWindow that is resizable to some extent, but generally size-constrained. It can only become smaller, not larger than with what it starts. Questions about your intentions:

    • top rectangle "red" is always to stay at constant height?
    • width of rectangles is not the problem here, right? They always fill the entire window width. I suppose this is what you want?
    • when you shrink the window vertically, neither middle rectangle "green" shrinks nor bottom rectangle "blue" moves upwards. Instead, "green" stays at constant height and "blue" eventually vanishes below window border. Is this what you wanted or do you want "green" to shrink and "blue" to keep its height when the window is shrunk?
    • when you click inside "green", "green"'s height is reduced and "blue" grows. Do you want "blue" to be of constant height all times instead? Or do you want "blue" to keep its height and create a blank area below it?
    • when I remove the last line and click inside "green", "green" shrinks, "blue" keeps size and position and a gap between "green" and "blue" is created. This is likely not what you want? (Otherwise you could just have left out that line already?)

    So, do you want a gap / blank area somewhere (below or above "blue") if "green" is shrunk, or do you want the new free space filled with something else? Or do my descriptions not match your experience when executing your piece of QML?



  • Hi,
    this is an example to explain my problem. What i want is quite simple : when i change the "green rectangle" height i want that the "blue rectangle" takes the place automaticaly. It seems that the Layout calculates the size (in my example the height only) at the creation and that when an item changes its size the calculation is not done anymore. I want the calculation done everytime an item cahnges its size.
    In the example i only changes the height.

    Of course if i change the size of the window i want the size of the items to change.

    This is for me the behaviour of a layout. Is there a way to change that ? Thanks
    Sincerely



  • @archqt said:

    this is an example to explain my problem. What i want is quite simple : when i change the "green rectangle" height i want that the "blue rectangle" takes the place automaticaly.

    I'm sorry, but this is exactly what already happens here, using your original code snipplet, when I click inside "green": "blue" grows upwards to fill the additional space. Doesn't the same happen on your installation?

    It seems that the Layout calculates the size (in my example the height only) at the creation and that when an item changes its size the calculation is not done anymore. I want the calculation done everytime an item cahnges its size.

    You should keep in mind that a layout manager is typically responsible for managing both positions and dimensions of its client items. It will do this continuously if you let it and don't interfere. If you want to change sizes of items manually / forcefully override them, then working with some anchors only may be a better option?



  • Hi,
    sure it works because i use an anchor (remove it). But as everything is in a layout when an item has it size that changes it should say to the Layout that size changed so the Layout can recalculate it.
    In my real project what i have done is this : i have 3 éléments and the second element can be hidden or not (depends if the user wanna see the values in it). The third element draws line, square...depending of the data in the second element.
    What i did is that i use Layout to manage size, and i use only visible property for the second element.
    So when second element is hidden the third element takes all the size (good news). But for a better design approch i decided to modify the size of the second elements (and with a behavior i do a dynamic animation) instead of using the visible property and....it doesn't work at all the third element doesn't change its size.
    So my real answer is : Why when i change visible (false/true) to the second element it works but when i modify only the height of it, it doesn't work ?
    Thanks
    Sincerely



  • Hi again,
    strange, when i click in the green rectangle it changes it size but when i resize the window the size came back to the original size ? why ?
    Sincerely

    import QtQuick 2.2
    import QtQuick.Layouts 1.1
    import QtQuick.Controls 1.1

    ApplicationWindow {
    width: layoutC.implicitWidth
    height: layoutC.implicitHeight

    ColumnLayout {
        id: layoutC
        anchors.fill: parent
        Rectangle {
            id: rect1
            color: "red"
            visible: true
            onWidthChanged: console.log("Rectangle 1 Width : "+width)
            Layout.fillHeight: false // Doesn't extend
            Layout.fillWidth: true // Doesn't extend
            Layout.minimumHeight: 50
            Layout.maximumHeight: 100
        }
        Rectangle {
            id: rect2
            color: "#028000"
            //width: rectangle.width
            height: 150
            onHeightChanged: console.log("Rectangle 2 Height : "+height)
            Layout.fillHeight: false // Doesn't extend
            Layout.fillWidth: true // Doesn't extend
            Layout.minimumHeight: 50
            Layout.maximumHeight: 300
            MouseArea {
                anchors.fill: parent
                onClicked: {
                    if (rect2.height==100) {
                        rect2.height=200
                        //rect3.height-=100 // Not Good i Know it is to illustrate : Remove it
                    }
                    else {
                        rect2.height=100
                        //rect3.height+=100 // Not Good i Know it is to illustrate : Remove it
                    }
                    console.log("clicked")
                }
            }
        }
        Rectangle {
            id: rect3
            color: "#0500ff"
            onHeightChanged: console.log("Rectangle 3 Height : "+height)
            Layout.fillHeight: true // Doesn't extend
            Layout.fillWidth: true // Doesn't extend
            Layout.minimumHeight: 50
            //anchors.top: rect2.bottom // Remove it and you will see that
        }
    }
    

    }



  • @archqt
    How about this approach then? (Simplified!) When you resize the window, "red" and "green" keep their constant height, while "blue" fills all remaining bottom space. However, the size of "green" can be changed forcefully. Here, by clicking into it.

    ApplicationWindow {
        width: 300; height: 300
        Column {
            anchors.fill: parent
            Rectangle {
                width: parent.width
                color: "red"
                height: 50 }
            Rectangle {
                id: green
                color: "green"
                height: 50
                width: parent.width
                MouseArea {
                    anchors.fill: parent
                    onClicked: green.height ^= 128 } }
            Rectangle {
                color: "blue"
                width: parent.width
                height: parent.height - y } } }
    

    Note that this approach doesn't use ColumnLayout but Column. Check the difference: as I mentioned before, ColumnLayout interferes with explicit positioning and sizing. Also, you must not mix anchors and absolute positioning, especially not in the same dimension. This approach uses width and height only., no single-dimensional anchors. y is managed entirely by the Column. As the QtQuick documentation states:

    anchor-based layouts cannot be mixed with absolute positioning. If an item specifies its x position and also sets anchors.left, or anchors its left and right edges but additionally sets a width, the result is undefined, as it would not be clear whether the item should use anchoring or absolute positioning. The same can be said for setting an item's y and height with anchors.top and anchors.bottom, or setting anchors.fill as well as width or height. The same applies when using positioners such as Row and Grid, which may set the item's x and y properties.



  • Hi,
    thanks for the reply. I know that Layout and anchors can't be mixed, it was just to illustrate the thing. So i guess that i must either use anchors or columns/rows to position my items else it won't work at all.
    The thing "strange" is that it works with visible property, so i thought that it could work too with height/width.
    Thanks for everything
    Sincerely


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.