Search code examples
qtlayoutqml

How to evenly shrink items in layout to make space for more items


Initially, I have four items with a specific size. Once a 5th item gets added, I would like to shrink the size of all items to make space inside the layout.

Window {
 width: 640
 height: 480
 visible: true
 id: root

 Item {
    id: col
    width: 300
    height: 200
    anchors.centerIn: parent

    RowLayout {
        id: row
        spacing: 10
        anchors.centerIn: parent

        Rectangle {
            Layout.minimumWidth: 30
            Layout.preferredWidth: 60
            Layout.preferredHeight: 20
            Layout.fillWidth: true
            color: "red"
        }
        Rectangle {
            Layout.minimumWidth: 30
            Layout.preferredWidth: 60
            Layout.preferredHeight: 20
            color: "blue"
            Layout.fillWidth: true
        }
        Rectangle {
            Layout.minimumWidth: 30
            Layout.preferredWidth: 60
            Layout.preferredHeight: 20
            color: "green"
            Layout.fillWidth: true
        }
        Rectangle {
            Layout.minimumWidth: 30
            Layout.preferredWidth: 60
            Layout.preferredHeight: 20
            color: "green"
            Layout.fillWidth: true
        }
        Rectangle {
            Layout.minimumWidth: 30
            Layout.preferredWidth: 60
            Layout.preferredHeight: 20
            color: "blue"
        }
    }
}

// for visualization
Rectangle {
    width: col.width
    height: col.height
    x: col.x
    y: col.y
    color: "black"
    opacity: 0.3
 }
}

The items should have a size of 60 if there's space to fit all items, or scale down to 30 if there isn't. Any ideas how I would accomplish that?

Items fit in layout

Items should shrink to fit RowLayout


Solution

  • You were almost there: Set Layout.maximumWidth instead of Layout.preferredWidth and make sure all the elements have Layout.fillWidth set to true. Also, the layout element itself must have the correct size for fillWidth to work. So replace centerIn with fill in this case.

    Here is your snippet; corrected and rewritten to make it easier to try out different numbers of elements.

    import QtQuick 2.14
    import QtQuick.Layouts 1.14
    import QtQuick.Controls 2.14
    import QtQuick.Window 2.14
    
    Window {
        width: 640
        height: 480
        visible: true
        id: root
    
        Item {
            id: col
            width: 300
            height: 200
            anchors.centerIn: parent
    
            RowLayout {
                id: row
                spacing: 10
                anchors.fill: parent
    
                Repeater {
                    model: spinBox.value
                    delegate: Rectangle {
                        Layout.minimumWidth: 30
                        Layout.maximumWidth: 60
                        Layout.preferredHeight: 20
                        Layout.fillWidth: true
                        color: ["red", "blue", "green", "green", "blue"][index % 5]
                    }
                }
            }
        }
    
        // for visualization
        Rectangle {
            width: col.width
            height: col.height
            x: col.x
            y: col.y
            color: "black"
            opacity: 0.3
        }
    
        SpinBox {
            id: spinBox
            from: 1; to: 10
            value: 5
        }
    }