Modelle und Ansichten in Qt Quick
Die meisten Anwendungen müssen Daten aufbereiten und anzeigen. „ Qt Quick “ nutzt die Konzepte von Modellen, Ansichten und Delegaten zur Datenanzeige. Diese modularisieren die Visualisierung von Daten, um dem Entwickler oder Designer die Kontrolle über die verschiedenen Aspekte der Daten zu ermöglichen. Ein Entwickler kann eine Listenansicht mit nur geringen Änderungen an den Daten gegen eine Rasteransicht austauschen. Ebenso ermöglicht die Kapselung einer Dateninstanz in einem Delegaten dem Entwickler, festzulegen, wie die Daten dargestellt oder verarbeitet werden sollen.

- Modell – enthält die Daten und deren Struktur. Es gibt verschiedene QML-Typen zum Erstellen von Modellen.
- Ansicht – ein Container, der die Daten anzeigt. Die Ansicht kann die Daten in einer Liste oder einem Raster darstellen.
- Delegat – legt fest, wie die Daten in der Ansicht dargestellt werden sollen. Das Delegat nimmt jede Dateneinheit aus dem Modell auf und kapseln sie. Der Zugriff auf die Daten erfolgt über das Delegat. Das Delegat kann Daten auch in bearbeitbare Modelle zurückschreiben (z. B. im `onAccepted`-Handler eines ` TextField`).
Um Daten zu visualisieren, binden Sie die Eigenschaft „ model “ der Ansicht an ein Modell und die Eigenschaft „ delegate “ an eine Komponente oder einen anderen kompatiblen Typ.
Anzeigen von Daten mit Ansichten
Ansichten sind Container für Sammlungen von Elementen. Sie verfügen über zahlreiche Funktionen und lassen sich an stilistische oder verhaltensbezogene Anforderungen anpassen.
Im Basisumfang der grafischen Typen von „ Qt Quick “ ist eine Reihe von Standardansichten enthalten:
- ListView - ordnet Elemente in einer horizontalen oder vertikalen Liste an
- GridView - ordnet Elemente in einem Raster innerhalb des verfügbaren Platzes an
- PathView - ordnet Elemente entlang eines Pfades an
- TableView - ordnet Daten aus einem „ QAbstractTableModel “ in einer Tabelle an
- TreeView - ordnet Daten aus einer „ QAbstractItemModel “ in einer Baumstruktur an
Diese Typen verfügen über Eigenschaften und Verhaltensweisen, die für den jeweiligen Typ spezifisch sind. Weitere Informationen finden Sie in der jeweiligen Dokumentation.
Darüber hinaus Qt Quick Controls enthält einige zusätzliche Ansichten und Delegaten, deren Darstellung an den Anwendungsstil angepasst ist, zum Beispiel „ HorizontalHeaderView “ und „ VerticalHeaderView “.
Ansichten gestalten
Ansichten lassen sich mithilfe von Dekorationseigenschaften wie header, footer und section visuell anpassen. Durch die Bindung eines Objekts – in der Regel eines anderen visuellen Objekts – an diese Eigenschaften lassen sich die Ansichten dekorieren. Eine Fußzeile kann beispielsweise einen Rectangle -Typ enthalten, der Rahmen anzeigt, oder eine Kopfzeile, die ein Logo über der Liste anzeigt.
Angenommen, ein bestimmter Verein möchte seine Mitgliederliste mit seinen Markenfarben gestalten. Eine Mitgliederliste befindet sich in einem „ model “, und das „ delegate “ zeigt den Inhalt des Modells an.
ListModel {
id: nameModel
ListElement { name: "Alice" }
ListElement { name: "Bob" }
ListElement { name: "Jane" }
ListElement { name: "Harry" }
ListElement { name: "Wendy" }
}
Component {
id: nameDelegate
Text {
required property string name
text: name
font.pixelSize: 24
width: ListView.view.width
}
}Der Verein kann die Mitgliederliste gestalten, indem er visuelle Objekte an die Eigenschaften „ header “ und „ footer “ bindet. Das visuelle Objekt kann inline, in einer anderen Datei oder in einem Typ „ Component “ definiert werden.
ListView {
anchors.fill: parent
clip: true
model: nameModel
delegate: nameDelegate
header: bannercomponent
footer: Rectangle {
width: parent.width; height: 30;
gradient: clubcolors
}
highlight: Rectangle {
color: "lightgray"
}
}
Component { //instantiated when header is processed
id: bannercomponent
Rectangle {
id: banner
width: parent.width; height: 50
gradient: clubcolors
border {color: "#9EDDF2"; width: 2}
Text {
anchors.centerIn: parent
text: "Club Members"
font.pixelSize: 32
}
}
}
Gradient {
id: clubcolors
GradientStop { position: 0.0; color: "#8EE2FE"}
GradientStop { position: 0.66; color: "#7ED2EE"}
}
Maus- und Touch-Verarbeitung
Die Ansichten verarbeiten das Ziehen und Wischen ihres Inhalts, jedoch nicht die Touch-Interaktion mit den einzelnen Delegaten. Damit die Delegaten auf Touch-Eingaben reagieren können, z. B. um die Eigenschaft ` currentIndex` zu setzen, muss der Delegat ein ` MouseArea ` mit der entsprechenden Touch-Verarbeitungslogik bereitstellen.
Beachten Sie, dass bei einer Einstellung von ` highlightRangeMode ` auf ` StrictlyEnforceRange ` der `currentIndex` durch das Ziehen/Wischen der Ansicht beeinflusst wird, da die Ansicht stets sicherstellt, dass der ` currentIndex ` innerhalb des festgelegten Hervorhebungsbereichs liegt.
ListView-Abschnitte
ListView Der Inhalt kann in Abschnitte gruppiert werden, wobei zugehörige Listenelemente entsprechend ihrer Abschnitte beschriftet werden. Darüber hinaus können die Abschnitte mit Delegaten gestaltet werden.
Eine Liste kann eine Liste enthalten, in der die Namen von Personen und das Team, dem die jeweilige Person angehört, aufgeführt sind.
ListModel {
id: nameModel
ListElement { name: "Alice"; team: "Crypto" }
ListElement { name: "Bob"; team: "Crypto" }
ListElement { name: "Jane"; team: "QA" }
ListElement { name: "Victor"; team: "QA" }
ListElement { name: "Wendy"; team: "Graphics" }
}
Component {
id: nameDelegate
Text {
required property string name
text: name;
font.pixelSize: 24
anchors.left: parent.left
anchors.leftMargin: 2
}
}Der Typ „ ListView “ verfügt über die angehängte Eigenschaft „ section “, mit der benachbarte und verwandte Typen zu einem Abschnitt zusammengefasst werden können. Die Eigenschaft „ section.property “ legt fest, welche Eigenschaft des Listentyps als Abschnitte verwendet werden soll. Die Eigenschaft „ section.criteria “ kann bestimmen, wie die Abschnittsnamen angezeigt werden, und die Eigenschaft „ section.delegate “ ähnelt der Delegate-Eigenschaft der Ansichten.
ListView {
anchors.fill: parent
model: nameModel
delegate: nameDelegate
focus: true
highlight: Rectangle {
color: "lightblue"
width: parent.width
}
section {
property: "team"
criteria: ViewSection.FullString
delegate: Rectangle {
color: "#b0dfb0"
width: parent.width
height: childrenRect.height + 4
Text { anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 16
font.bold: true
text: section
}
}
}
}
Ansichtsdelegaten
Ansichten benötigen einen Delegaten, um ein Element in einer Liste visuell darzustellen. Eine Ansicht visualisiert jedes Element der Liste gemäß der vom Delegaten definierten Vorlage. Auf Elemente in einem Modell kann sowohl über die Eigenschaft „ index “ als auch über die Eigenschaften des Elements zugegriffen werden.
Component {
id: petdelegate
Text {
id: label
font.pixelSize: 24
text: index === 0 ? type + " (default)" : type
required property int index
required property string type
}
}
Positionierung von Ansichtsdelegaten
Der Ansichtstyp bestimmt, wie die Elemente positioniert werden. „ ListView “ positioniert die Elemente in einer geraden Linie, abhängig von der Eigenschaft „ orientation “, während eine „ GridView “ sie in einem zweidimensionalen Raster anordnet. Es wird nicht empfohlen, direkt an „ x “ und „ y “ zu binden, da das Layoutverhalten der Ansicht stets Vorrang vor jeglicher Positionsbindung hat.
Zugriff auf Ansichten und Modelle über Delegaten
GridView.view Auf die Listenansicht, an die der Delegat gebunden ist, kann vom Delegaten aus über die Eigenschaft „ ListView.view “ zugegriffen werden. Ebenso steht den Delegaten die Eigenschaft „ GridView “ zur Verfügung. Das entsprechende Modell und seine Eigenschaften sind daher über „ ListView.view.model “ zugänglich. Darüber hinaus sind auch alle im Modell definierten Signale oder Methoden zugänglich.
Dieser Mechanismus ist nützlich, wenn Sie beispielsweise denselben Delegaten für mehrere Ansichten verwenden möchten, dabei aber möchten, dass Dekorationen oder andere Merkmale für jede Ansicht unterschiedlich sind, und Sie möchten, dass diese unterschiedlichen Einstellungen als Eigenschaften der jeweiligen Ansichten vorliegen. Ebenso könnte es von Interesse sein, auf bestimmte Eigenschaften des Modells zuzugreifen oder diese anzuzeigen.
Im folgenden Beispiel zeigt der Delegat die Eigenschaft „language“ des Modells an, und die Farbe eines der Felder hängt von der Eigenschaft „fruit_color“ der Ansicht ab.
Rectangle {
width: 200; height: 200
ListModel {
id: fruitModel
property string language: "en"
ListElement {
name: "Apple"
cost: 2.45
}
ListElement {
name: "Orange"
cost: 3.25
}
ListElement {
name: "Banana"
cost: 1.95
}
}
Component {
id: fruitDelegate
Row {
id: fruit
required property string name
required property real cost
Text {
text: " Fruit: " + fruit.name
color: fruit.ListView.view.fruit_color
}
Text {
text: " Cost: $" + fruit.cost
}
Text {
text: " Language: " + fruit.ListView.view.model.language
}
}
}
ListView {
property color fruit_color: "green"
model: fruitModel
delegate: fruitDelegate
anchors.fill: parent
}
}Modelle
Daten werden dem Delegaten über benannte Datenrollen bereitgestellt, an die sich der Delegat binden kann. Hier ist ein „ ListModel “ mit zwei Rollen, „type“ und „age“, sowie ein „ ListView “ mit einem Delegaten, der sich an diese Rollen bindet, um deren Werte anzuzeigen:
import QtQuick
Item {
width: 200
height: 250
ListModel {
id: myModel
ListElement { type: "Dog"; age: 8; noise: "meow" }
ListElement { type: "Cat"; age: 5; noise: "woof" }
}
component MyDelegate : Text {
required property string type
required property int age
text: type + ", " + age
// WRONG: Component.onCompleted: () => console.log(noise)
// The above line would cause a ReferenceError
// as there is no required property noise,
// and the presence of the required properties prevents
// noise from being injected into the scope
}
ListView {
anchors.fill: parent
model: myModel
delegate: MyDelegate {}
}
}In den meisten Fällen sollten Sie Pflicht-Eigenschaften verwenden, um Modelldaten an Ihre Delegaten zu übergeben. Wenn ein Delegat Pflicht-Eigenschaften enthält, prüft die QML-Engine, ob der Name einer Pflicht-Eigenschaft mit dem einer Modellrolle übereinstimmt. Ist dies der Fall, wird diese Eigenschaft an den entsprechenden Wert aus dem Modell gebunden.
In seltenen Sonderfällen möchten Sie möglicherweise die Modelleigenschaften nicht als erforderliche Eigenschaften, sondern über den QML-Kontext übergeben. Wenn in Ihrem Delegaten keine erforderlichen Eigenschaften vorhanden sind, werden die benannten Rollen als Kontexteigenschaften bereitgestellt:
import QtQuick
Item {
width: 200; height: 250
ListModel {
id: myModel
ListElement { type: "Dog"; age: 8 }
ListElement { type: "Cat"; age: 5 }
}
Component {
id: myDelegate
Text { text: type + ", " + age }
}
ListView {
anchors.fill: parent
model: myModel
delegate: myDelegate
}
}Kontext-Eigenschaften sind für Werkzeuge nicht sichtbar und verhindern, dass der „Qt Quick “-Compiler Ihren Code optimiert. Sie erschweren es, die spezifischen Daten zu ermitteln, die Ihr Delegat erwartet. Es gibt keine Möglichkeit, den QML-Kontext explizit aus QML heraus zu füllen. Wenn Ihre Komponente erwartet, dass Daten über den QML-Kontext übergeben werden, können Sie diesen nur an Stellen verwenden, an denen der richtige Kontext auf native Weise bereitgestellt wird. Dies kann Ihr eigener C++-Code oder die spezifischen Implementierungen umgebender Elemente sein. Umgekehrt können erforderliche Eigenschaften auf verschiedene Weise aus QML heraus oder über native Mittel gesetzt werden. Daher verringert die Übergabe von Daten über den QML-Kontext die Wiederverwendbarkeit Ihrer Komponenten.
Wenn es einen Namenskonflikt zwischen den Eigenschaften des Modells und den Eigenschaften des Delegaten gibt, kann stattdessen mit dem qualifizierten Modellnamen auf die Rollen zugegriffen werden. Wenn beispielsweise ein Typ „ Text “ (nicht erforderliche) Eigenschaften „type“ oder „age“ hätte, würde der Text im obigen Beispiel diese Eigenschaftswerte anstelle der Werte für „type“ und „age“ aus dem Modellelement anzeigen. In diesem Fall hätten die Eigenschaften stattdessen als „ model.type “ und „ model.age “ referenziert werden können, um sicherzustellen, dass der Delegat die Eigenschaftswerte aus dem Modellelement anzeigt. Damit dies funktioniert, müssen Sie in Ihrem Delegaten eine „ model “-Eigenschaft als erforderlich festlegen (es sei denn, Sie verwenden Kontexteigenschaften).
Dem Delegaten steht außerdem eine spezielle Indexrolle zur Verfügung, die den Index des Elements im Modell enthält. Beachten Sie, dass dieser Index auf -1 gesetzt wird, wenn das Element aus dem Modell entfernt wird. Wenn Sie eine Bindung an die Index-Rolle herstellen, stellen Sie sicher, dass die Logik die Möglichkeit berücksichtigt, dass der Index -1 ist, d. h., dass das Element nicht mehr gültig ist. (Normalerweise wird das Element in Kürze zerstört, aber es ist möglich, die Zerstörung des Delegaten in einigen Ansichten über die angehängte Eigenschaft „ delayRemove “ zu verzögern.)
Beachten Sie, dass Sie als Modell sowohl Ganzzahlen als auch Arrays verwenden können:
Repeater {
model: ["one", "two", "three"]
Text {
required property string modelData
text: modelData
}
}Solche Modelle stellen jeder Instanz des Delegaten einen einzelnen, anonymen Datenwert zur Verfügung. Der Zugriff auf diesen Datenwert ist der Hauptgrund für die Verwendung von „modelData“, doch auch andere Modelle stellen „modelData“ bereit.
Das über die Rolle „model“ bereitgestellte Objekt verfügt über eine Eigenschaft mit einem leeren Namen. Diese anonyme Eigenschaft enthält die „modelData“. Darüber hinaus verfügt das über die Rolle „model“ bereitgestellte Objekt über eine weitere Eigenschaft namens „modelData“. Diese Eigenschaft ist veraltet und enthält ebenfalls die „modelData“.
Zusätzlich zur „model“-Rolle wird eine „modelData“-Rolle bereitgestellt. Die „modelData“-Rolle enthält dieselben Daten wie die „modelData“-Eigenschaft und die anonyme Eigenschaft des über die „model“-Rolle bereitgestellten Objekts.
Die Unterschiede zwischen der „model“-Rolle und den verschiedenen Möglichkeiten, auf „modelData“ zuzugreifen, sind wie folgt:
- Bei Modellen ohne benannte Rollen (wie z. B. Ganzzahlen oder ein Array von Zeichenketten) werden die Daten über die „modelData“-Rolle bereitgestellt. In diesem Fall enthält die „modelData“-Rolle nicht unbedingt ein Objekt. Im Fall eines Integer-Modells würde sie eine Ganzzahl enthalten (den Index des aktuellen Modellelements). Im Fall eines Arrays von Zeichenketten würde sie eine Zeichenkette enthalten. Die „model“-Rolle enthält weiterhin ein Objekt, jedoch ohne Eigenschaften für benannte Rollen. „model“ enthält jedoch nach wie vor seine üblichen „modelData“- und „anonymous“-Eigenschaften.
- Wenn das Modell nur eine benannte Rolle hat, enthält die „modelData“-Rolle dieselben Daten wie die benannte Rolle. Es handelt sich nicht unbedingt um ein Objekt, und es enthält die benannte Rolle nicht wie üblich als benannte Eigenschaft. Die „model“-Rolle enthält in diesem Fall weiterhin ein Objekt mit der benannten Rolle als Eigenschaft sowie die „modelData“- und anonymen Eigenschaften.
- Bei Modellen mit mehreren Rollen wird die Rolle „modelData“ nur als erforderliche Eigenschaft bereitgestellt, nicht als Kontexteigenschaft. Dies ist auf die Abwärtskompatibilität mit älteren Versionen von Qt zurückzuführen.
Die anonyme Eigenschaft auf „model“ ermöglicht es Ihnen, Delegaten sauber zu schreiben, die sowohl ihre Modelldaten als auch den Rollennamen, auf den sie reagieren sollen, als Eigenschaften von außen erhalten. Sie können ein Modell ohne oder mit nur einer benannten Rolle und einer leeren Zeichenkette als Rolle bereitstellen. Dann führt eine Bindung, die einfach auf „ model[role] “ zugreift, das aus, was Sie erwarten. Für diesen Fall müssen Sie keinen speziellen Code hinzufügen.
Hinweis: Auf die Rollen „model“, „index“ und „modelData“ kann nicht zugegriffen werden, wenn der Delegat erforderliche Eigenschaften enthält, es sei denn, er verfügt ebenfalls über erforderliche Eigenschaften mit übereinstimmenden Namen.
QML stellt im Rahmen der integrierten QML-Typen mehrere Arten von Datenmodellen bereit. Darüber hinaus können Modelle mit Qt C++ erstellt und anschließend „ QQmlEngine “ zur Verwendung durch QML-Komponenten zur Verfügung gestellt werden. Informationen zum Erstellen dieser Modelle finden Sie in den Artikeln „Verwendung von C++-Modellen mit Qt Quick -Ansichten “ und „Erstellen von QML-Typen “.
Die Positionierung von Elementen aus einem Modell kann mithilfe eines „ Repeater “ erfolgen.
Listenmodell
ListModel ist eine einfache Hierarchie von Typen, die in QML definiert sind. Die verfügbaren Rollen werden durch die Eigenschaften des „ ListElement “ festgelegt.
ListModel {
id: fruitModel
ListElement {
name: "Apple"
cost: 2.45
}
ListElement {
name: "Orange"
cost: 3.25
}
ListElement {
name: "Banana"
cost: 1.95
}
}Das obige Modell verfügt über zwei Rollen: „name “ und „cost“. Diese können über einen „ ListView “-Delegaten gebunden werden, zum Beispiel:
ListView {
anchors.fill: parent
model: fruitModel
delegate: Row {
id: delegate
required property string name
required property real cost
Text { text: "Fruit: " + delegate.name }
Text { text: "Cost: $" + delegate.cost }
}
}ListModel bietet Methoden zur direkten Bearbeitung des „ ListModel “ über JavaScript. In diesem Fall bestimmt das erste eingefügte Element die Rollen, die für alle Ansichten verfügbar sind, die das Modell verwenden. Wenn beispielsweise ein leeres „ ListModel “ erstellt und über JavaScript gefüllt wird, sind die durch die erste Einfügung bereitgestellten Rollen die einzigen, die in der Ansicht angezeigt werden:
ListModel { id: fruitModel }
...
MouseArea {
anchors.fill: parent
onClicked: fruitModel.append({"cost": 5.95, "name":"Pizza"})
}Wenn auf „ MouseArea “ geklickt wird, verfügt „ fruitModel “ über zwei Rollen: „cost“ und „name“. Selbst wenn später weitere Rollen hinzugefügt werden, werden von den Ansichten, die das Modell verwenden, nur die ersten beiden berücksichtigt. Um die im Modell verfügbaren Rollen zurückzusetzen, rufen Sie „ ListModel::clear()“ auf.
XML-Modell
XmlListModel ermöglicht die Erstellung eines Modells aus einer XML-Datenquelle. Die Rollen werden über den Typ „ XmlListModelRole “ festgelegt. Der Typ muss importiert werden.
import QtQml.XmlListModelDas folgende Modell verfügt über drei Rollen: „title“, „link“ und „pubDate“:
XmlListModel {
id: feedModel
source: "http://rss.news.yahoo.com/rss/oceania"
query: "/rss/channel/item"
XmlListModelRole { name: "title"; elementName: "title" }
XmlListModelRole { name: "link"; elementName: "link" }
XmlListModelRole { name: "pubDate"; elementName: "pubDate" }
}Die Eigenschaft „ query “ legt fest, dass der „ XmlListModel “ für jeden „ <item> “ im XML-Dokument ein Modellelement generiert.
Die RSS-News-Demo zeigt, wie „ XmlListModel “ zur Anzeige eines RSS-Feeds verwendet werden kann.
Objektmodell
ObjectModel enthält die visuellen Elemente, die in einer Ansicht verwendet werden sollen. Wenn ein „ ObjectModel “ in einer Ansicht verwendet wird, benötigt die Ansicht keinen Delegaten, da der „ ObjectModel “ bereits den visuellen Delegaten (Elemente) enthält.
Im folgenden Beispiel werden drei farbige Rechtecke in einem „ ListView “ platziert.
import QtQuick 2.0
import QtQml.Models 2.1
Rectangle {
ObjectModel {
id: itemModel
Rectangle { height: 30; width: 80; color: "red" }
Rectangle { height: 30; width: 80; color: "green" }
Rectangle { height: 30; width: 80; color: "blue" }
}
ListView {
anchors.fill: parent
model: itemModel
}
}Ganzzahlen als Modelle
Eine ganze Zahl kann als Modell verwendet werden, das eine bestimmte Anzahl von Typen enthält. In diesem Fall weist das Modell keine Datenrollen auf.
Im folgenden Beispiel wird ein „ ListView “ mit fünf Elementen erstellt:
Item {
width: 200; height: 250
Component {
id: itemDelegate
Text {
required property int index
text: "I am item number: " + index
}
}
ListView {
anchors.fill: parent
model: 5
delegate: itemDelegate
}
}Hinweis: Die Anzahl der Elemente in einem ganzzahligen Modell ist auf 100.000.000begrenzt .
Objektinstanzen als Modelle
Eine Objektinstanz kann verwendet werden, um ein Modell mit einem einzigen Objekttyp zu definieren. Die Eigenschaften des Objekts werden als Rollen bereitgestellt.
Das folgende Beispiel erstellt eine Liste mit einem Element, das die Farbe des Texts „myText“ anzeigt. Beachten Sie die Verwendung der vollständig qualifizierten Eigenschaft „model.color“, um Konflikte mit der Eigenschaft „color“ des Typs „Text“ im Delegaten zu vermeiden.
Rectangle {
width: 200; height: 250
Text {
id: myText
text: "Hello"
color: "#dd44ee"
}
Component {
id: myDelegate
Text {
required property var model
text: model.color
}
}
ListView {
anchors.fill: parent
anchors.topMargin: 30
model: myText
delegate: myDelegate
}
}C++-Datenmodelle
Modelle können in C++ definiert und anschließend für QML verfügbar gemacht werden. Dieser Mechanismus ist nützlich, um bestehende C++-Datenmodelle oder anderweitig komplexe Datensätze für QML zugänglich zu machen.
Weitere Informationen finden Sie im Artikel „Verwendung von C++-Modellen mit Qt Quick -Ansichten “.
Array-Modelle
Sie können JavaScript-Arrays und verschiedene Arten von QML-Listen als Modelle verwenden. Die Elemente der Liste werden gemäß den oben beschriebenen Regeln als „model“ und „modelData“ bereitgestellt: Einzelne Daten wie Ganzzahlen oder Zeichenketten werden als einzelnes „modelData“ bereitgestellt. Strukturierte Daten wie JavaScript-Objekte oder QObjects werden als strukturiertes „model“ und „modelData“ bereitgestellt.
Die einzelnen Modellrollen werden ebenfalls bereitgestellt, wenn Sie sie als erforderliche Eigenschaften anfordern. Da wir im Voraus nicht wissen können, welche Objekte in einem Array vorkommen, wird jede erforderliche Eigenschaft in einem Delegaten gefüllt, möglicherweise mit einer Typumwandlung von „ undefined “ in den erforderlichen Typ. Die einzelnen Modellrollen werden jedoch nicht über den QML-Kontext bereitgestellt. Sie würden alle anderen Kontexteigenschaften überschreiben.
Repeater

Repeater erstellen Elemente aus einer Vorlage zur Verwendung mit Positionern, wobei sie Daten aus einem Modell nutzen. Die Kombination von Repeatern und Positionern ist eine einfache Möglichkeit, viele Elemente anzuordnen. Ein „ Repeater “-Element wird in einen Positioner eingefügt und generiert Elemente, die der umschließende Positioner anordnet.
Jeder Repeater erstellt eine bestimmte Anzahl von Elementen, indem er jedes Datenelement aus einem Modell – das über die Eigenschaft „ model “ angegeben wird – mit dem Vorlagenelement kombiniert, das als untergeordnetes Element innerhalb des Repeaters definiert ist. Die Gesamtzahl der Elemente richtet sich nach der Datenmenge im Modell.
Das folgende Beispiel zeigt einen Repeater, der zusammen mit einem „Grid“-Element verwendet wird, um eine Reihe von „Rectangle“-Elementen anzuordnen. Das Repeater-Element erzeugt eine Reihe von 24 Rechtecken, die das „Grid“-Element in einer 5×5-Anordnung positioniert.
import QtQuick
Rectangle {
width: 400
height: 400
color: "black"
Grid {
x: 5
y: 5
rows: 5
columns: 5
spacing: 10
Repeater {
model: 24
Rectangle {
id: delegate
required property int index
width: 70
height: 70
color: "lightgreen"
Text {
text: delegate.index
font.pointSize: 30
anchors.centerIn: parent
}
}
}
}
}Die Anzahl der von einem „Repeater“ erstellten Elemente wird durch dessen Eigenschaft „ count “ gespeichert. Es ist nicht möglich, diese Eigenschaft so festzulegen, dass die Anzahl der zu erstellenden Elemente bestimmt wird. Stattdessen verwenden wir, wie im obigen Beispiel, eine Ganzzahl als Modell.
Weitere Informationen finden Sie im Dokument „QML-Datenmodelle “.
Wenn es sich bei dem Modell um eine Zeichenfolgenliste handelt, steht dem Delegaten außerdem die übliche schreibgeschützte Eigenschaft „ modelData “ zur Verfügung, die die Zeichenfolge enthält. Beispiel:
|
Es ist auch möglich, einen Delegaten als Vorlage für die von einem „Repeater“ erstellten Elemente zu verwenden. Dies wird über die Eigenschaft „ delegate “ festgelegt.
Ändern von Modelldaten
Alle relevanten Ansichten verfügen über eine Eigenschaft namens „delegateModelAccess“, die festlegt, ob und wie Sie Modelldaten über den Delegaten ändern können. In den meisten Anwendungsfällen sollten Sie diese Eigenschaft auf „DelegateModel.ReadWrite“ setzen. Dadurch kann Ihr Delegat Modelldaten auf die flexibelste Weise ändern. Alternativ können Sie sie auf „DelegateModel.ReadOnly“ setzen, wenn Sie nicht möchten, dass der Delegat Modelldaten überhaupt ändert.
Die folgende Tabelle beschreibt detailliert alle Werte, die die Eigenschaft annehmen kann.
| DelegateModel.Qt5ReadWrite | Der Delegat kann allen von der Ansicht bereitgestellten Kontexteigenschaften Werte zuweisen, um das entsprechende Modellelement zu ändern. Darüber hinaus kann er auch Eigenschaften des Objekts ` model `, die entweder als Kontexteigenschaft oder als erforderliche Eigenschaft bereitgestellt werden, mit demselben Effekt Werte zuweisen. Der Delegat kann jedoch keine Modelldaten ändern, indem er Werten an erforderliche Eigenschaften zuweist, die von der Ansicht gefüllt werden. Wenn Sie einer erforderlichen Eigenschaft eines Delegaten einen Wert zuweisen, wird die Bindung unterbrochen, die die erforderliche Eigenschaft anhand der Modelldaten aktualisiert. Dadurch behält die erforderliche Eigenschaft den von Ihnen zugewiesenen Wert bei, selbst wenn sich das Modell später ändert. DelegateModel.Qt5ReadWrite ist der Standardwert von delegateModelAccess. |
| DelegateModel.ReadOnly | Der Delegat kann weder Werte an von der Ansicht bereitgestellte Kontext-Eigenschaften noch an Eigenschaften des Objekts „ model “ zuweisen. Das Zuweisen eines Werts an eine von der Ansicht gefüllte erforderliche Eigenschaft unterbricht weder die interne Bindung noch verändert es Modelldaten. Die erforderliche Eigenschaft behält den ihr zugewiesenen Wert bei, bis sich das Modellelement erneut ändert. |
| DelegateModel.ReadWrite | Der Delegat kann allen von der Ansicht bereitgestellten Kontexteigenschaften Werte zuweisen, um das entsprechende Modellelement zu ändern. Darüber hinaus kann er auch Eigenschaften des „ model “-Objekts, die entweder als Kontexteigenschaft oder als erforderliche Eigenschaft bereitgestellt werden, mit demselben Effekt Werte zuweisen. Der Delegat kann Modelldaten auch ändern, indem er Werte den von der Ansicht gefüllten erforderlichen Eigenschaften zuweist. Die Zuweisung eines Werts zu einer erforderlichen Eigenschaft leitet den Wert an das jeweilige Modellelement weiter, ohne interne Bindungen zu unterbrechen. |
Einige Modelle sind Objekte mit eigenständigen Identitäten, auf die die Ansicht verweist. Das ursprüngliche Objekt ist die einzige Quelle der Wahrheit für die Erstellung von Delegaten. Es wird nicht kopiert. Solche Modelle werden beim Schreiben über Delegaten sichtbar aktualisiert.
Andere Modelle verfügen über keine eigenständige Identität und werden bei der Zuweisung an die Ansicht kopiert. Bei solchen Modellen werden beim Schreiben über den Delegaten lediglich die internen Strukturen der Ansicht aktualisiert. Das ursprüngliche Modell bleibt unverändert.
Im Allgemeinen verfügen QML-Objekttypen über eigenständige Identitäten, QML-Werttypen hingegen nicht. ListModel, alles, was von ` QAbstractItemModel` abgeleitet ist, sowie entweder eine einzelne Instanz eines Objekttyps oder eine Liste von Instanzen von Objekttypen werden also aktualisiert, wenn sie als Modell übergeben und über den Delegaten geschrieben werden. JavaScript-Arrays, Listen von Werttypen oder einfache Zahlen werden jedoch nicht aktualisiert, wenn Sie Modelldaten über den Delegaten ändern.
Darüber hinaus müssen Sie bei der Implementierung Ihres eigenen C++-Modells die Methode ` setData ` implementieren, um von Delegaten übergebene Aktualisierungen zu empfangen.
Angenommen, ein auf „ QAbstractItemModel “ basierendes C++-Modell, das die Methode „ setData “ implementiert, ist als QML-Typ mit dem Namen „ EditableModel “ registriert. Daten könnten dann wie folgt in das Modell geschrieben werden:
ListView {
anchors.fill: parent
model: EditableModel {}
// Make sure that changes to the required property are propagated
delegateModelAccess: DelegateModel.ReadWrite
delegate: TextEdit {
required property string edit
width: ListView.view.width
height: 30
text: edit
Keys.onReturnPressed: edit = text
}
}Sie können Modelldaten auch ändern, indem Sie das ` model `-Objekt wie folgt bearbeiten:
ListView {
anchors.fill: parent
model: EditableModel {}
delegate: TextEdit {
required property QtObject model
width: ListView.view.width
height: 30
text: model.edit
Keys.onReturnPressed: model.edit = text
}
}Hinweis: Die Rolle „ edit “ entspricht „ Qt::EditRole “. Eine Übersicht über die integrierten Rollennamen finden Sie unter roleNames(). In der Praxis werden in Modellen jedoch in der Regel benutzerdefinierte Rollen registriert.
Weitere Informationen finden Sie im Artikel „Verwenden von C++-Modellen mit Qt Quick -Ansichten “.
Verwendung von Übergängen
Übergänge können verwendet werden, um Elemente zu animieren, die zu einem Positionierer hinzugefügt, innerhalb dieses verschoben oder aus diesem entfernt werden.
Übergänge zum Hinzufügen von Elementen gelten sowohl für Elemente, die als Teil eines Positioners erstellt werden, als auch für solche, die neu zugeordnet werden, um zu untergeordneten Elementen eines Positioners zu werden.
Übergänge beim Entfernen von Elementen gelten sowohl für Elemente innerhalb eines Positionierers, die gelöscht werden, als auch für solche, die aus einem Positionierer entfernt und im Dokument neuen übergeordneten Elementen zugeordnet werden.
Hinweis: Das Setzen der Deckkraft von Elementen auf Null führt nicht dazu, dass sie aus dem Positionierer verschwinden. Sie können entfernt und erneut hinzugefügt werden, indem die Eigenschaft „visible“ geändert wird.
© 2026 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.
