不使用 GridView 或 ListView 但使用 c++ 模型的结构化布局的 QML 解决方案
QML solution for a structured layout not using a GridView or ListView but using a c++ model
我正在尝试通过仅使用 Row
和 Column
来想出一种以非常结构化的方式表示某些项目的方法。我从 Qt Widgets 得到了灵感,在那里你可以用水平和垂直布局做任何事情,并且有一个漂亮的 UI。问题是我仍然希望创建我的 QML 项目的数据来自 c++,这需要某种模型。据我所知,模型只能绑定到 PathView
、GridView
或 ListView
。此外,该数据将根据 QML UI 发出的一些 "add" 和 "remove" 操作动态变化。有没有办法在模型中使用 Row
和 Column
?
让我们假设您的模型应填充 Grid
、Row
和 Column
:
ListModel {
id: lm
ListElement { target: "Grid"; content: "green" }
ListElement { target: "Grid"; content: "blue" }
ListElement { target: "Grid"; content: "yellow" }
ListElement { target: "Grid"; content: "orange" }
ListElement { target: "Row"; content: "green" }
ListElement { target: "Row"; content: "blue" }
ListElement { target: "Row"; content: "yellow" }
ListElement { target: "Row"; content: "orange" }
ListElement { target: "Column"; content: "green" }
ListElement { target: "Column"; content: "blue" }
ListElement { target: "Column"; content: "yellow" }
ListElement { target: "Column"; content: "orange" }
}
Row {
id: row
spacing: 2
anchors {
top: parent.top
left: parent.left
right: parent.right
}
}
Column {
id: column
spacing: 2
anchors {
top: row.bottom; topMargin: 2
left: parent.left
bottom: parent.bottom
}
}
Grid {
id: grid
spacing: 2
columns: 2
anchors {
top: row.bottom
left: column.right
right: parent.right
bottom: parent.bottom
margins: 102
}
}
您可以像这样使用 Repeater
:
Repeater {
model: lm
delegate: Rectangle {
width: 100
height: 100
parent: (target === "Grid" ? grid :
(target === "Row" ? row :
(target === "Column" ? column :
null)))
color: content
}
}
这可能会给你一个警告:
QQuickItem::stackAfter: Cannot stack after 0x3d5cb18, which must be a sibling
或者您可以使用 Instantiator
,这将需要创建一个额外的 QtObject
,但您不会收到任何警告。
Instantiator {
model: lm
delegate: QtObject {
property Item child: Rectangle {
width: 100
height: 100
parent: (target === "Grid" ? grid :
(target === "Row" ? row :
(target === "Column" ? column :
null)))
color: content
}}
}
您甚至可以为一个模型条目设置多个对象...
Instantiator {
model: lm
delegate: QtObject {
property Item child1: Rectangle {
width: 100
height: 100
parent: (target === "Row" ? row :
(target === "Column" ? column :
null)) // If "Grid" this thing will be created but not shown.
color: content
}
property Item gridItem: Button {
width: 100
height: 30
text: content
onClicked: rootWin.color = content
parent: grid
}
}
}
我正在尝试通过仅使用 Row
和 Column
来想出一种以非常结构化的方式表示某些项目的方法。我从 Qt Widgets 得到了灵感,在那里你可以用水平和垂直布局做任何事情,并且有一个漂亮的 UI。问题是我仍然希望创建我的 QML 项目的数据来自 c++,这需要某种模型。据我所知,模型只能绑定到 PathView
、GridView
或 ListView
。此外,该数据将根据 QML UI 发出的一些 "add" 和 "remove" 操作动态变化。有没有办法在模型中使用 Row
和 Column
?
让我们假设您的模型应填充 Grid
、Row
和 Column
:
ListModel {
id: lm
ListElement { target: "Grid"; content: "green" }
ListElement { target: "Grid"; content: "blue" }
ListElement { target: "Grid"; content: "yellow" }
ListElement { target: "Grid"; content: "orange" }
ListElement { target: "Row"; content: "green" }
ListElement { target: "Row"; content: "blue" }
ListElement { target: "Row"; content: "yellow" }
ListElement { target: "Row"; content: "orange" }
ListElement { target: "Column"; content: "green" }
ListElement { target: "Column"; content: "blue" }
ListElement { target: "Column"; content: "yellow" }
ListElement { target: "Column"; content: "orange" }
}
Row {
id: row
spacing: 2
anchors {
top: parent.top
left: parent.left
right: parent.right
}
}
Column {
id: column
spacing: 2
anchors {
top: row.bottom; topMargin: 2
left: parent.left
bottom: parent.bottom
}
}
Grid {
id: grid
spacing: 2
columns: 2
anchors {
top: row.bottom
left: column.right
right: parent.right
bottom: parent.bottom
margins: 102
}
}
您可以像这样使用 Repeater
:
Repeater {
model: lm
delegate: Rectangle {
width: 100
height: 100
parent: (target === "Grid" ? grid :
(target === "Row" ? row :
(target === "Column" ? column :
null)))
color: content
}
}
这可能会给你一个警告:
QQuickItem::stackAfter: Cannot stack after 0x3d5cb18, which must be a sibling
或者您可以使用 Instantiator
,这将需要创建一个额外的 QtObject
,但您不会收到任何警告。
Instantiator {
model: lm
delegate: QtObject {
property Item child: Rectangle {
width: 100
height: 100
parent: (target === "Grid" ? grid :
(target === "Row" ? row :
(target === "Column" ? column :
null)))
color: content
}}
}
您甚至可以为一个模型条目设置多个对象...
Instantiator {
model: lm
delegate: QtObject {
property Item child1: Rectangle {
width: 100
height: 100
parent: (target === "Row" ? row :
(target === "Column" ? column :
null)) // If "Grid" this thing will be created but not shown.
color: content
}
property Item gridItem: Button {
width: 100
height: 30
text: content
onClicked: rootWin.color = content
parent: grid
}
}
}