使用中继器填​​充 GridLayout

Posted

技术标签:

【中文标题】使用中继器填​​充 GridLayout【英文标题】:Populate GridLayout with Repeater 【发布时间】:2015-10-06 12:00:42 【问题描述】:

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

Title Value

我的目标是得到一个GridLayout,在每行的第一个单元格中包含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                        |
|            |                                       |
|            |                                       |
+------------+---------------------------------------+

【问题讨论】:

【参考方案1】:

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

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 组件发生的情况不同。

此解决方案有一些缺点,但如果您的目的主要是从模型中打印纯数据,那就很好了。

【讨论】:

请注意我遇到了一个错误bugreports.qt.io/browse/QTBUG-65121,如果它对您不起作用,您可以随时将一行与 2 列组合在一起【参考方案2】:

您可以使用GridLayout.flow 指定单元格的填充顺序,即按行(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
            
        
    

【讨论】:

【参考方案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;
            
        
    

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

【讨论】:

好的,谢谢。我将尝试@BaCaRoZzo 建议的基于列的解决方案。即使我不确定结果是否是我想要的。我认为每行的第一个单元格将具有不同的宽度。让我们看看我是否错了(希望如此^^) 填充列的建议版本工作得很好,但生成的布局不是我想要的。每行的第一个单元格具有不同的宽度。所以这并不是真正的问题解决方案。我会尝试@folibis 的有线解决方案......如果它工作它还不够有线:) Naaah,不要使用它,我已经发布了它作为你不应该做的例子。因此,如果使用Column,您可以为每个Label 设置相同的宽度。或者,更准确地说,您应该查看模型。【参考方案4】:

在Repeater的委托中的Item内嵌套任意数量的元素,并在Item完成时将它们重新设置为GridLayout。

GridLayout 
    id: grid
    anchors.centerIn: parent
    columns: 2
    rowSpacing: 5
    columnSpacing: 5
    anchors.margins: 5

    Repeater 
        model: [
             title: "title1 that's long", value: "value1" ,
             title: "title2 medium",      value: "value2" ,
             title: "title3",             value: "value3" 
        ]
        delegate: Item 
            Component.onCompleted: 
                while (children.length)  children[0].parent = grid; 
            

            Label 
                Layout.alignment: Qt.AlignRight
                color: "gray"
                text: modelData.title
            
            TextArea 
                Layout.fillWidth: true
                font.bold: true
                text: modelData.value
            
        
    

【讨论】:

以上是关于使用中继器填​​充 GridLayout的主要内容,如果未能解决你的问题,请参考以下文章

jQuery Autocomplete - 在选择之前不要填​​充文本输入(鼠标或输入)

swarm测试极简指南如何使用测试网络的小钱包充Gas费

如何使用Axure中继器创建复杂的列表

26.中继器数据的添加与删除

https网络编程——如何利用中继证书(凭证)建立客户端证书

https网络编程——如何利用中继证书(凭证)建立客户端证书