1
votes

How do you add multiple elements to a GridLayout using a single Repeater?

The GridLayout component ensures that rows and columns are sized to fit to the largest item in each cell, but if you want to populate it using a Repeater it seems impossible because a Repeater can only have one delegate.

There is another SO page asking how to do it without a wrapping Item, but I've never seen a wrapping Item solution and don't know why it would not be preferable.

How would you create the following?

screen capture showing data optimally aligned into rows and columns

Here is the model data for that image:

model: [  // JSON model
    {
        name: "February:",
        types: [
            { name: "R-1", size: 24, color: "red" },
            { name: "O--2", size: 16, color: "orange" },
            { name: "Y---3", size: 8, color: "yellow" },
        ]
    },
    {
        name: "March:",
        types: [
            { name: "G-1", size: 24, color: "green" },
        ]
    },
    {
        name: "April:",
        types: [
            { name: "B-1", size: 24, color: "blue" },
            { name: "I--2", size: 16, color: "indigo" },
            { name: "V---3", size: 8, color: "violet" },
        ]
    },
]
1
Why the downvote? - pixelgrease

1 Answers

0
votes

Add multiple Items as children to the Repeater's delegate Item and use JavaScript to reparent them into the GridLayout when the delegate Item is completed.

GridLayout {
    id: grid
    anchors.centerIn: parent
    columns: 3

    Repeater {
        Item {
            id: wrappingItem
            Component.onCompleted: reparentChildren(this, grid)

            Text {
                Layout.alignment: Qt.AlignTop|Qt.AlignRight
                Layout.rowSpan: modelData.types.length
                text: modelData.name
            }
            Repeater {
                model: modelData.types

                Item {
                    Component.onCompleted: reparentChildren(this, wrappingItem)

                    Text {
                        Layout.alignment: Qt.AlignTop|Qt.AlignHCenter
                        text: modelData.name
                    }
                    Rectangle {
                        width: modelData.size; height: width
                        color: modelData.color
                    }
                }
            }
        }

        model: [  // JSON model
            {
                name: "February:",
                types: [
                    { name: "R-1", size: 24, color: "red" },
                    { name: "O--2", size: 16, color: "orange" },
                    { name: "Y---3", size: 8, color: "yellow" },
                ]
            },
            {
                name: "March:",
                types: [
                    { name: "G-1", size: 24, color: "green" },
                ]
            },
            {
                name: "April:",
                types: [
                    { name: "B-1", size: 24, color: "blue" },
                    { name: "I--2", size: 16, color: "indigo" },
                    { name: "V---3", size: 8, color: "violet" },
                ]
            },
        ]
    }
}