使用 Repeater 填充 GridLayout
Populate GridLayout with Repeater
我尝试使用 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 |
| | |
| | |
+------------+---------------------------------------+
模型视图原则假设每个模型节点由不同的委托组件对象显示。所以我建议您听听@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;
}
}
}
}
但是在实际项目中使用它太奇怪了。
你可以在一个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
组件时发生的情况不同。
此解决方案有一些缺点,但如果您的目的主要是打印模型中的纯数据,则此解决方案很好。
在使用GridLayout.TopToBottom
时可以使用GridLayout.flow
to specify in which order the cells should be filled, i.e. row- (GridLayout.LeftToRight
) or column-wise (GridLayout.TopToBottom
). Note that you should specify the 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
}
}
}
}
在 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
}
}
}
}
我尝试使用 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 |
| | |
| | |
+------------+---------------------------------------+
模型视图原则假设每个模型节点由不同的委托组件对象显示。所以我建议您听听@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;
}
}
}
}
但是在实际项目中使用它太奇怪了。
你可以在一个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
组件时发生的情况不同。
此解决方案有一些缺点,但如果您的目的主要是打印模型中的纯数据,则此解决方案很好。
在使用GridLayout.TopToBottom
时可以使用GridLayout.flow
to specify in which order the cells should be filled, i.e. row- (GridLayout.LeftToRight
) or column-wise (GridLayout.TopToBottom
). Note that you should specify the 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
}
}
}
}
在 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
}
}
}
}