dh1*_*1tw 20 qt listview qml qtquick2
我想知道是否可以使用(几个)不同的代表进行QML ListView.
根据ListView模型中的单个对象,我想用不同的委托来可视化对象.
这段代码解释了我想要实现的目标:
main.qml
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
visible: true
ListModel {
id: contactsModel
ListElement {
name: "Bill Smith"
position: "Engineer"
}
ListElement {
name: "John Brown"
position: "Engineer"
}
ListElement {
name: "Sam Wise"
position: "Manager"
}
}
ListView {
id: contactsView
anchors.left: parent.left
anchors.top: parent.top
width: parent.width
height: parent.height
orientation: Qt.Vertical
spacing: 10
model: contactsModel
delegate: {
if (position == "Engineer") return Employee; //<--- depending on condition, load Contact{}
else if (position == "Manager") return Manager; //<--- depending on condition, load Person{}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Employee.qml(我想用作委托的一个可能的组件)
import QtQuick 2.4
Rectangle{
width: 200
height: 50
color: ListView.isCurrentItem ? "#003366" : "#585858"
border.color: "gray"
border.width: 1
Text{
anchors.centerIn: parent
color: "white"
text: name
}
}
Run Code Online (Sandbox Code Playgroud)
Manager.qml(我想用作委托的其他组件)
import QtQuick 2.4
Rectangle{
width: 200
height: 50
color: "red"
border.color: "blue"
border.width: 1
Text{
anchors.centerIn: parent
color: "white"
text: name
}
}
Run Code Online (Sandbox Code Playgroud)
我很感激任何建议!谢谢!
Aur*_*ert 15
我遇到了同样的问题,Qt文档提供了一个很好的答案:http://doc.qt.io/qt-5/qml-qtquick-loader.html#using-a-loader-within-a-视图代表
最简单的解决办法是内联Component与Loader设置source文件:
ListView {
id: contactsView
anchors.left: parent.left
anchors.top: parent.top
width: parent.width
height: parent.height
orientation: Qt.Vertical
spacing: 10
model: contactsModel
delegate: Component {
Loader {
source: switch(position) {
case "Engineer": return "Employee.qml"
case "Manager": return "Manager.qml"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
任何使用尝试都Loader.srcComponent将导致缺少模型中的任何变量(包括index).变量存在的唯一方法是将子项Component放在main中Component,但是只有一个可以存在,所以它是无用的.
And*_*rii 11
我相信最好为所有类型实现一个基本委托,position根据position使用的任何其他数据属性加载具体实现Loader
BaseDelegate {
property var position
Loader {
sourceComponent: {
switch(position) {
case "Engineer": return engineerDelegate
}
}
}
Component {
id: engineerDelegate
Rectangle {
Text { }
}
}
}
Run Code Online (Sandbox Code Playgroud)
我实现如下:
ListView {
id: iranCitiesList
model: sampleModel
delegate: Loader {
height: childrenRect.height
width: parent.width
sourceComponent: {
switch(itemType) {
case "image" :
return imageDel;
case "video":
return videoDel;
}
}
}
ImageDelegate { id: imageDel }
VideoDelegate { id: videoDel }
}
Run Code Online (Sandbox Code Playgroud)
ImageDelegate.qml
Component {
Image { /*...*/ }
}
Run Code Online (Sandbox Code Playgroud)
VideoDelegate.qml
Component {
Item { /*....*/ }
}
Run Code Online (Sandbox Code Playgroud)
最后请注意,检查代表的宽度和高度.在我的情况下,我不得不再次设置我的代表的宽度和高度Loader.
祝你好运 - 穆萨维
小智 6
现在最简单的方法是使用DelegateChooser。这也允许您编辑委托的属性,这是使用 Loader 更难做的事情!
示例灵感来自文档:
import QtQuick 2.14
import QtQuick.Controls 2.14
import Qt.labs.qmlmodels 1.0
ListView {
width: 640; height: 480
ListModel {
id: contactsModel
ListElement {
name: "Bill Smith"
position: "Engineer"
}
ListElement {
name: "John Brown"
position: "Engineer"
}
ListElement {
name: "Sam Wise"
position: "Manager"
}
}
DelegateChooser {
id: chooser
role: "position"
DelegateChoice { roleValue: "Manager"; Manager { ... } }
DelegateChoice { roleValue: "Employee"; Employee { ... } }
}
model: contractsModel
delegate: chooser
}
Run Code Online (Sandbox Code Playgroud)
当然,这是可能的。ListView.delegate是一种指向 a 的指针Component,它将绘制项目,以便您可以更改它。
例如:
Employee { id: delegateEmployee }
Manager { id: delegateManager}
...
ListView {
property string position
delegate: position == "Engineer" ? delegateEmployee : delegateManager
}
Run Code Online (Sandbox Code Playgroud)