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{}
}
}
}
Employee.qml(デリゲートとして使用したいコンポーネントの1つ)
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
}
}
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
}
}
私はアドバイスをいただければ幸いです!ありがとう!
私は同じ問題を抱えていましたが、Qtドキュメントはかなり良い答えを提供しています: http://doc.qt.io/qt-5/qml-qtquick-loader.html#using-a-loader- within-a-view-delegate
最も簡単な解決策は、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"
}
}
}
}
Loader.srcComponent
を使用しようとすると、モデルから変数が失われます(index
を含む)。変数が存在する唯一の方法は、子Component
がメインComponent
内にあることですが、存在できるのは1つだけなので、それは役に立ちません。
position
またはposition
を使用する他のデータプロパティに応じて具体的な実装をロードするすべての種類のLoader
に1つの基本デリゲートを実装する方が良いと思います
BaseDelegate {
property var position
Loader {
sourceComponent: {
switch(position) {
case "Engineer": return engineerDelegate
}
}
}
Component {
id: engineerDelegate
Rectangle {
Text { }
}
}
}
私はそれを次のように実装しました:
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 }
}
ImageDelegate.qml
Component {
Image { /*...*/ }
}
VideoDelegate.qml
Component {
Item { /*....*/ }
}
最後に、デリゲートの幅と高さを確認してください。私の場合、デリゲートの幅と高さをLoader
に再度設定する必要がありました。
頑張ってください-Mousavi
タイプが2つしかない限り、次のコードは保守が簡単で理解も簡単です。
delegate: Item {
Employee { visible = position === "Engineer" }
Manager { visible = position === "Manager" }
}
タイプの数が増える場合は、ifステートメントの地獄に簡単につながるため、適切なソリューションではありません。