ListModel QML Type
Definiert eine Freiform-Listen-Datenquelle. Mehr...
Import Statement: | import QtQml.Models |
Eigenschaften
- count : int
- dynamicRoles : bool
Methoden
- append(jsobject dict)
- clear()
- object get(int index)
- insert(int index, jsobject dict)
- move(int from, int to, int n)
- remove(int index, int count)
- set(int index, jsobject dict)
- setProperty(int index, string property, variant value)
- sync()
Ausführliche Beschreibung
Das ListModel ist ein einfacher Container mit ListElement Definitionen, die jeweils Datenrollen enthalten. Der Inhalt kann dynamisch oder explizit in QML definiert werden.
Die Anzahl der Elemente im Modell kann über die Eigenschaft count ermittelt werden. Zur Bearbeitung des Inhalts des Modells stehen eine Reihe bekannter Methoden zur Verfügung, darunter append(), insert(), move(), remove() und set(). Diese Methoden akzeptieren Wörterbücher als Argumente; diese werden vom Modell in ListElement Objekte übersetzt.
Elemente können über das Modell mit der Methode setProperty() manipuliert werden, mit der die Rollen des angegebenen Elements festgelegt und geändert werden können.
ListModel erbt von QAbstractListModel und bietet dessen Q_INVOKABLE Methoden. Sie können z. B. QAbstractItemModel::index verwenden, um eine QModelIndex für eine Zeile und Spalte abzurufen.
Beispielverwendung
Das folgende Beispiel zeigt ein ListModel mit drei Elementen mit den Rollen "name" und "cost".
import QtQuick ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 } ListElement { name: "Orange" cost: 3.25 } ListElement { name: "Banana" cost: 1.95 } }
Rollen (Eigenschaften) in jedem Element müssen mit einem Kleinbuchstaben beginnen und sollten für alle Elemente in einem Modell gleich sein. Die Dokumentation ListElement enthält weitere Richtlinien für die Definition von Elementen.
Da das Beispielmodell eine id
-Eigenschaft enthält, kann diese von Ansichten referenziert werden, wie z. B. die ListView in diesem Beispiel:
import QtQuick Rectangle { width: 200; height: 200 ListModel { id: fruitModel ... } Component { id: fruitDelegate Row { spacing: 10 Text { text: name } Text { text: '$' + cost } } } ListView { anchors.fill: parent model: fruitModel delegate: fruitDelegate } }
Es ist möglich, dass Rollen Listendaten enthalten. Im folgenden Beispiel erstellen wir eine Liste von Obstattributen:
ListModel { id: fruitModel ListElement { name: "Apple" cost: 2.45 attributes: [ ListElement { description: "Core" }, ListElement { description: "Deciduous" } ] } ListElement { name: "Orange" cost: 3.25 attributes: [ ListElement { description: "Citrus" } ] } ListElement { name: "Banana" cost: 1.95 attributes: [ ListElement { description: "Tropical" }, ListElement { description: "Seedless" } ] } }
Der Delegat zeigt alle Obstattribute an:
Component { id: fruitDelegate Item { width: 200; height: 50 Text { id: nameField; text: name } Text { text: '$' + cost; anchors.left: nameField.right } Row { anchors.top: nameField.bottom spacing: 5 Text { text: "Attributes:" } Repeater { model: attributes Text { text: description } } } } }
Ändern von Listenmodellen
Der Inhalt eines ListModel kann mit den Methoden clear(), append(), set(), insert() und setProperty() erstellt und geändert werden. Ein Beispiel:
Component { id: fruitDelegate Item { width: 200; height: 50 Text { text: name } Text { text: '$' + cost; anchors.right: parent.right } // Double the price when clicked. MouseArea { anchors.fill: parent onClicked: fruitModel.setProperty(index, "cost", cost * 2) } } }
Beachten Sie, dass bei der dynamischen Erstellung von Inhalten die Menge der verfügbaren Eigenschaften nicht geändert werden kann, wenn sie einmal festgelegt wurde. Die Eigenschaften, die dem Modell zuerst hinzugefügt werden, sind die einzigen zulässigen Eigenschaften des Modells.
Verwendung von Threaded List Models mit WorkerScript
ListModel kann zusammen mit WorkerScript verwendet werden, um auf ein Listenmodell von mehreren Threads aus zuzugreifen. Dies ist nützlich, wenn Listenänderungen synchron sind und einige Zeit in Anspruch nehmen: Die Listenoperationen können in einen anderen Thread verschoben werden, um ein Blockieren des Haupt-GUI-Threads zu vermeiden.
Hier ist ein Beispiel, das WorkerScript verwendet, um periodisch die aktuelle Zeit an ein Listenmodell anzuhängen:
Timer { id: timer interval: 2000; repeat: true running: true triggeredOnStart: true onTriggered: { var msg = {'action': 'appendCurrentTime', 'model': listModel}; worker.sendMessage(msg); } }
Die enthaltene Datei dataloader.mjs
sieht wie folgt aus:
WorkerScript.onMessage = function(msg) { if (msg.action == 'appendCurrentTime') { var data = {'time': new Date().toTimeString()}; msg.model.append(data); msg.model.sync(); // updates the changes to the list } }
Der Timer im Hauptbeispiel sendet Nachrichten an das Arbeitsskript, indem er WorkerScript::sendMessage() aufruft. Wenn diese Nachricht empfangen wird, wird WorkerScript.onMessage()
in dataloader.mjs
aufgerufen, das die aktuelle Zeit an das Listenmodell anhängt.
Beachten Sie den Aufruf von sync() aus dem externen Thread. Sie müssen sync() aufrufen, sonst werden die von diesem Thread an der Liste vorgenommenen Änderungen nicht im Listenmodell des Hauptthreads wiedergegeben.
Siehe auch Datenmodelle und Qt Qml.
Eigenschaft Dokumentation
count : int |
Die Anzahl der Dateneinträge im Modell.
dynamicRoles : bool |
Standardmäßig ist der Typ einer Rolle festgelegt, wenn die Rolle zum ersten Mal verwendet wird. Wenn Sie zum Beispiel eine Rolle mit dem Namen "data" erstellen und ihr eine Zahl zuweisen, können Sie der Rolle "data" keine Zeichenkette mehr zuweisen. Wenn jedoch die Eigenschaft dynamicRoles aktiviert ist, ist der Typ einer bestimmten Rolle nicht festgelegt und kann von Element zu Element unterschiedlich sein.
Die Eigenschaft dynamicRoles muss festgelegt werden, bevor Daten zu ListModel hinzugefügt werden, und sie muss vom Hauptthread aus festgelegt werden.
Bei einem ListModel, dessen Daten statisch definiert sind (über die ListElement QML-Syntax), kann die Eigenschaft dynamicRoles nicht aktiviert werden.
Die Verwendung einer ListModel mit aktivierten dynamischen Rollen ist mit erheblichen Leistungseinbußen verbunden. Die Kosten variieren von Plattform zu Plattform, sind aber in der Regel 4-6 mal langsamer als bei der Verwendung statischer Rollentypen.
Aufgrund der Leistungseinbußen bei der Verwendung dynamischer Rollen sind diese standardmäßig deaktiviert.
Methode Dokumentation
append(jsobject dict) |
clear() |
object get(int index) |
Gibt das Element unter index im Listenmodell zurück. Dies ermöglicht den Zugriff auf die Elementdaten oder deren Änderung über JavaScript:
Component.onCompleted: { fruitModel.append({"cost": 5.95, "name":"Jackfruit"}); console.log(fruitModel.get(0).cost); fruitModel.get(0).cost = 10.95; }
Die Adresse index muss ein Element in der Liste sein.
Beachten Sie, dass Eigenschaften des zurückgegebenen Objekts, die selbst Objekte sind, ebenfalls Modelle sind und diese get()-Methode für den Zugriff auf Elemente verwendet wird:
fruitModel.append(..., "attributes": [{"name":"spikes","value":"7mm"}, {"name":"color","value":"green"}]); fruitModel.get(0).attributes.get(1).value; // == "green"
Warnung: Es ist nicht garantiert, dass das zurückgegebene Objekt gültig bleibt. Es sollte nicht in Eigenschaftsbindungen oder zur Speicherung von Daten über Änderungen seiner Herkunft ListModel verwendet werden.
insert(int index, jsobject dict) |
Fügt dem Listenmodell an der Position index ein neues Element mit den Werten in dict hinzu.
fruitModel.insert(2, {"cost": 5.95, "name":"Pizza"})
index muss sich auf ein bestehendes Element in der Liste beziehen oder auf ein Element nach dem Ende der Liste (entspricht append).
Verschiebt n Elemente from eine Position to eine andere.
Die Bereiche from und to müssen vorhanden sein, z. B. um die ersten 3 Einträge an das Ende der Liste zu verschieben:
fruitModel.move(0, fruitModel.count - 3, 3)
Siehe auch append().
Löscht count Anzahl der Elemente unter index aus dem Modell.
Siehe auch clear().
set(int index, jsobject dict) |
Ändert das Element unter index im Listenmodell mit den Werten unter dict. Eigenschaften, die nicht in dict vorkommen, bleiben unverändert.
fruitModel.set(3, {"cost": 5.95, "name":"Pizza"})
Wenn index gleich count() ist, wird ein neues Element an die Liste angehängt. Andernfalls muss index ein Element in der Liste sein.
Siehe auch append().
Ändert die property des Elements an index im Listenmodell in value.
fruitModel.setProperty(3, "cost", 5.95)
Das index muss ein Element in der Liste sein.
Siehe auch append().
sync() |
Schreibt alle nicht gespeicherten Änderungen in das Listenmodell, nachdem es von einem Arbeitsskript aus geändert wurde.
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.