qt - Diferentes delegados para QML ListView
qtquick2 (5)
Claro, es posible. ListView.delegate
es un tipo de puntero a un Component
que dibujará los elementos para que pueda cambiarlo.
Por ejemplo:
Employee { id: delegateEmployee }
Manager { id: delegateManager}
...
ListView {
property string position
delegate: position == "Engineer" ? delegateEmployee : delegateManager
}
Me gustaría saber si es posible usar (varios) delegados diferentes para un ListView
QML.
Dependiendo del objeto individual en el modelo ListView
, me gustaría visualizar los objetos con diferentes delegados.
Esta pieza de código explica lo que quiero lograr:
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 (un componente posible que me gustaría usar como delegado)
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 (otro componente que me gustaría usar como delegado)
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
}
}
¡Apreciaría cualquier consejo! ¡Gracias!
Creo que sería mejor implementar un delegado base para todo tipo de position
que cargue la implementación concreta en función de la position
o cualquier otra propiedad de datos utilizando Loader
BaseDelegate {
property var position
Loader {
sourceComponent: {
switch(position) {
case "Engineer": return engineerDelegate
}
}
}
Component {
id: engineerDelegate
Rectangle {
Text { }
}
}
}
En la medida en que solo tiene dos tipos, el siguiente código es tan fácil de mantener como fácil de entender:
delegate: Item {
Employee { visible = position === "Engineer" }
Manager { visible = position === "Manager" }
}
En caso de que el número de tipos crezca, no es una solución adecuada, ya que fácilmente conduce a una sentencia if if.
He tenido el mismo problema, la documentación de Qt proporciona una respuesta bastante buena: http://doc.qt.io/qt-5/qml-qtquick-loader.html#using-a-loader-within-a-view-delegate
La solución más fácil es un Component
línea con un Loader
para establecer un archivo de 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"
}
}
}
}
Cualquier intento de usar Loader.srcComponent
hará que falte alguna variable del modelo (incluido el index
). La única forma de que las variables estén presentes es que el Component
esté dentro del Component
principal, pero entonces solo puede estar presente uno, por lo que es inútil.
Lo implementé de la siguiente manera:
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 { /*....*/ }
}
Última nota, consultar ancho y alto de delegados. En mi caso, tuve que establecer el ancho y la altura de mi delegado en el Loader
nuevo.
Buena suerte - Mousavi