qt listview qml qtquick2

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