首页 文章

使用Repeater填充GridLayout

提问于
浏览
3

我尝试使用 Repeater 将单元格添加到我的 GridLayout . 我的数据存储在模型中,每个元素包含两个属性:

  • Title

  • Value

我的目标是在第一个单元格中包含 Title ,在每行的第二个单元格中包含 Value .

GridLayout {
    id: someId
    columns: 2
    rowSpacing: 5
    columnSpacing: 5
    anchors.margins: 5
    anchors.left: parent.left
    anchors.right: parent.right

    Repeater {
        model: myModel
        Label {
            text: modelData.title
        }
        TextArea {
            text: modelData.value
        }
    }
}

但是QML Repeater 只允许一个元素 . 任何想法我怎么能得到我想要的布局?

+------------+---------------------------------------+
|            |                                       |
|  title0    |         value0                        |
|            |                                       |
|            |                                       |
+------------+---------------------------------------+
|            |                                       |
|            |                                       |
|  title1    |         value1                        |
|            |                                       |
|            |                                       |
+------------+---------------------------------------+
|            |                                       |
|  title2    |         value2                        |
|            |                                       |
|            |                                       |
+------------+---------------------------------------+

3 回答

  • 10

    您可以在 GridLayout 中简单地使用两个 Repeater ,如下所示:

    import QtQuick 2.5
    import QtQuick.Window 2.2
    import QtQuick.Layouts 1.1
    import QtQuick.Controls 1.4
    
    Window {
        width: 600; height: 400; visible: true
    
        GridLayout {
            id: grid
            anchors.fill: parent
            columns: 2
            rowSpacing: 5
            columnSpacing: 5
            anchors.margins: 5
            // example models
            property var titles: [ "title1", "title2", "title3", "title4", "title5" ]
            property var values: [ "value1", "value2", "value3", "value4", "value5" ]
    
            Repeater {
                model: grid.titles
                Label {
                    Layout.row: index
                    Layout.column: 0
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: modelData
                }
            }
    
            Repeater {
                model: grid.values
                TextArea {
                    Layout.row: index
                    Layout.column: 1
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: modelData
                }
            }
        }
    }
    

    index 参数可自由使用并存储模型的当前行 .

    通过使用 Layout.fillWidth 附加属性,您可以控制单列的 width .

    当然,属于列的每个单元格与该列的所有其他单元格具有相同的大小,这与使用两个 Column 组件时发生的情况不同 .

    这个解决方案有一些缺点,但如果你的目的主要是从模型打印普通数据,这是很好的 .

  • 3

    模型 - 视图原则假定每个模型节点由不同的委托组件对象显示 . 所以我建议你听听@ BaCaRoZzo的评论并用 Column 代替 GridLayout . 当然,QML非常灵活,您可以这样做:

    Component {
        id: labelDelegate
        Label { text: myList.get(_index / 2).title }
    }
    
    Component {
        id: textAreaDelegate
        TextArea { text: myList.get(_index / 2).value }
    }
    
    ListModel {
        id: myList
        ListElement {title: "title1"; value: "value1"}
        ListElement {title: "title2"; value: "value2"}
        ListElement {title: "title3"; value: "value3"}
    }
    
    GridLayout {
        anchors.fill: parent
        columns: 2
        Repeater {
            model: myList.count * 2
            delegate: Loader {
                property int _index: index
                sourceComponent: {
                    if(index % 2)
                        return textAreaDelegate;
                    else
                        return labelDelegate;
                }
            }
        }
    }
    

    但在实际项目中使用它太奇怪了 .

  • 2

    您可以使用GridLayout.flow指定应填充单元格的顺序,即row-( GridLayout.LeftToRight )或逐列( GridLayout.TopToBottom ) . 请注意,使用 GridLayout.TopToBottom 时应指定number of rows .

    使用此解决方案,skypjack的(简化)示例将变为:

    import QtQuick 2.5
    import QtQuick.Window 2.2
    import QtQuick.Layouts 1.1
    import QtQuick.Controls 1.4
    
    Window {
        width: 600; height: 400; visible: true
    
        GridLayout {
            anchors.fill: parent
    
            % specify the flow and number of rows
            flow: GridLayout.TopToBottom
            rows: repeater.count
    
            Repeater {
                id: repeater
                model: [ "title1", "title2", "title3", "title4", "title5", "title6" ] // example model
                Label {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: modelData
                }
            }
    
            Repeater {
                model: [ "value1", "value2", "value3", "value4", "value5", "value6" ]  // example model
                TextArea {
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    text: modelData
                }
            }
        }
    }
    

相关问题