使用中继器填充 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
中简单地使用两个Repeater
s,如下所示:
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 - 在选择之前不要填充文本输入(鼠标或输入)