Search code examples
qtlayoutqml

RowLayout does not dynamically resize based on content


I want some layouts defined in QML to automatically adjust to fit their contents. This works, but not dynamically, i.e. if the content changes the layout does not adapt. With the old-style (non-QML) Layout/Widget approach, this happened automatically.

Here is an example (my code looks different and consists of different files, but I pasted this MWE together to demonstrate the problem):

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.2

Window {
    id: root
    visible: true
    width: 640
    height: 480
    property var nbx: 3

    Column {
        RowLayout {
            Repeater {
                model: 3
                Rectangle {
                    width:  childrenRect.width     
                    height: childrenRect.height
                    color: "green"
                    ColumnLayout {
                        Rectangle {
                            height: 10
                        }
                        RowLayout {
                            Repeater {
                                model: root.nbx
                                Rectangle {
                                    width:  20
                                    height: 20
                                    color: "orange"
                                }
                            }
                        }
                    }
                }
            }
        }

        Button {
            text: "5 boxes"
            onClicked: root.nbx= 5;
        }
        Button {
            text: "2 boxes"
            onClicked: root.nbx = 2;
        }
    }
}

How can I achieve the same with QML?


Solution

  • You can make it work by setting the implicit size of the green Rectangle to the implicit size of the child ColumnLayout. I'm not exactly sure why, it seems the childrenRect properties are not propertly updated.

    import QtQuick 2.9
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.0
    import QtQuick.Layouts 1.2
    
    Window {
        id: root
        visible: true
        width: 640
        height: 480
        property var nbx: 3
    
        ColumnLayout {
            RowLayout {
    
                Repeater {
                    model: 3
    
                    Rectangle {
                        implicitHeight: col1.implicitHeight   // <--- here is the change
                        implicitWidth: col1.implicitWidth
                        color: "green"
    
                        ColumnLayout {
                            id: col1
    
                            Rectangle {
                                height: 10
                            }
                            RowLayout {
                                Repeater {
                                    model: root.nbx
                                    Rectangle {
                                        width:  20
                                        height: 20
                                        color: "orange"
                                    }
                                }
                            }
                        }
                    }
                }
            }
    
            Button {
                text: "5 boxes"
                onClicked: root.nbx= 5;
            }
            Button {
                text: "2 boxes"
                onClicked: root.nbx = 2;
            }
        }
    }