Modèles et vues dans Qt Quick
La plupart des applications doivent mettre en forme et afficher des données. Qt Quick s'appuie sur les notions de modèles, de vues et de délégués pour afficher les données. Ces éléments modularisent la visualisation des données afin de permettre au développeur ou au concepteur de contrôler les différents aspects de celles-ci. Un développeur peut remplacer une vue de liste par une vue en grille en apportant très peu de modifications aux données. De même, l'encapsulation d'une instance des données dans un délégué permet au développeur de définir la manière dont les données doivent être présentées ou traitées.

- Modèle: contient les données et leur structure. Il existe plusieurs types QML permettant de créer des modèles.
- Vue (View ) – un conteneur qui affiche les données. La vue peut afficher les données sous forme de liste ou de grille.
- Délégué – détermine la manière dont les données doivent apparaître dans la vue. Le délégué prend chaque unité de données du modèle et l’encapsule. Les données sont accessibles via le délégué. Le délégué peut également réécrire des données dans des modèles modifiables (par exemple, dans le gestionnaire onAccepted d’un « TextField »).
Pour visualiser les données, liez la propriété ` model ` de la vue à un modèle et la propriété ` delegate ` à un composant ou à un autre type compatible.
Affichage des données avec les vues
Les vues sont des conteneurs pour des collections d'éléments. Elles offrent de nombreuses fonctionnalités et peuvent être personnalisées pour répondre à des exigences de style ou de comportement.
Un ensemble de vues standard est fourni dans le jeu de base des types graphiques d'Qt Quick:
- ListView - organise les éléments sous forme de liste horizontale ou verticale
- GridView - organise les éléments en grille dans l'espace disponible
- PathView - organise les éléments le long d’un tracé
- TableView - organise les données d'une QAbstractTableModel sous forme de tableau
- TreeView - organise les données d'une base de données « QAbstractItemModel » sous forme d'arborescence
Ces types possèdent des propriétés et des comportements qui leur sont propres. Consultez leur documentation respective pour plus d'informations.
De plus, Qt Quick Controls contient quelques vues et délégués supplémentaires dont le style est adapté à celui de l'application, par exemple HorizontalHeaderView et VerticalHeaderView.
Décoration des vues
Les vues permettent une personnalisation visuelle grâce à des propriétés de décoration telles que header, footer et section. En associant un objet, généralement un autre objet visuel, à ces propriétés, les vues peuvent être décorées. Un pied de page peut inclure un type Rectangle affichant des bordures, ou un en-tête affichant un logo en haut de la liste.
Supposons qu’un club spécifique souhaite personnaliser sa liste de membres avec les couleurs de sa marque. Une liste de membres se trouve dans un ` model ` et la propriété ` delegate ` affichera le contenu du modèle.
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
}
}Le club peut personnaliser la liste des membres en associant des objets visuels aux propriétés header et footer. L’objet visuel peut être défini en ligne, dans un autre fichier ou dans un type de « Component ».
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"}
}
Gestion de la souris et des interactions tactiles
Les vues gèrent le glissement et le balayage de leur contenu, mais elles ne gèrent pas les interactions tactiles avec les délégués individuels. Pour que les délégués réagissent aux entrées tactiles, par exemple pour définir la propriété ` currentIndex`, un ` MouseArea ` doté de la logique de gestion tactile appropriée doit être fourni par le délégué.
Notez que si ` highlightRangeMode ` est défini sur ` StrictlyEnforceRange `, `currentIndex` sera affecté par le glissement ou le balayage de la vue, car celle-ci veillera toujours à ce que ` currentIndex ` se trouve dans la plage de mise en surbrillance spécifiée.
Sections de la ListView
ListView Le contenu peut être regroupé en sections, dans lesquelles les éléments de liste associés sont étiquetés en fonction de leur section. De plus, les sections peuvent être agrémentées de délégués.
Une liste peut contenir une liste indiquant les noms des personnes et l'équipe à laquelle chacune d'entre elles appartient.
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
}
}Le type « ListView » dispose de la propriété associée « section », qui permet de regrouper des types adjacents et liés au sein d’une section. La propriété « section.property » détermine quelle propriété du type de liste doit être utilisée pour définir les sections. La propriété « section.criteria » permet de définir le mode d’affichage des noms de section, tandis que la propriété « section.delegate » est similaire à la propriété « delegate » des vues.
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
}
}
}
}
Délégués de vue
Les vues ont besoin d’un délégué pour représenter visuellement un élément d’une liste. Une vue affiche chaque élément de la liste selon le modèle défini par le délégué. Les éléments d’un modèle sont accessibles via la propriété index ainsi que via les propriétés de l’élément.
Component {
id: petdelegate
Text {
id: label
font.pixelSize: 24
text: index === 0 ? type + " (default)" : type
required property int index
required property string type
}
}
Positionnement des délégués de vue
Le type de vue détermine la manière dont les éléments sont positionnés. Le type « ListView » positionne les éléments en ligne droite, en fonction de la propriété « orientation », tandis qu’une vue de type « GridView » peut les disposer selon une grille en deux dimensions. Il n’ est pas recommandé de lier directement les propriétés « x » et « y », car le comportement de mise en page de la vue prévaudra toujours sur toute liaison de position.
Accès aux vues et aux modèles à partir de délégués
GridView La vue de liste à laquelle le délégué est lié est accessible depuis le délégué via la propriété ListView.view. De même, l’ GridView.view est disponible pour les délégués. Le modèle correspondant et ses propriétés sont donc accessibles via ListView.view.model. De plus, tous les signaux ou méthodes définis dans le modèle sont également accessibles.
Ce mécanisme est utile lorsque vous souhaitez, par exemple, utiliser le même délégué pour plusieurs vues, mais que vous souhaitez que les décorations ou d’autres fonctionnalités soient différentes pour chaque vue, et que vous souhaitiez que ces différents paramètres soient des propriétés de chacune des vues. De même, il peut être intéressant d’accéder à certaines propriétés du modèle ou de les afficher.
Dans l'exemple suivant, le délégué affiche la propriété language du modèle, et la couleur de l'un des champs dépend de la propriété fruit_color de la vue.
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
}
}Modèles
Les données sont fournies au délégué via des rôles de données nommés auxquels celui-ci peut se lier. Voici un exemple d’ ListModel e comportant deux rôles, « type » et « age », ainsi qu’un exemple d’ ListView e avec un délégué qui se lie à ces rôles pour afficher leurs valeurs :
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 {}
}
}Dans la plupart des cas, vous devriez utiliser des propriétés obligatoires pour transmettre les données du modèle à vos délégués. Si un délégué contient des propriétés obligatoires, le moteur QML vérifiera si le nom d’une propriété obligatoire correspond à celui d’un rôle du modèle. Si c’est le cas, cette propriété sera liée à la valeur correspondante du modèle.
Dans de rares cas particuliers, vous pouvez souhaiter transférer les propriétés du modèle via le contexte QML plutôt que sous forme de propriétés obligatoires. Si votre délégué ne contient aucune propriété obligatoire, les rôles nommés sont fournis en tant que propriétés de contexte :
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
}
}Les propriétés de contexte sont invisibles pour les outils et empêchent l’ Qt Quick Compiler d’optimiser votre code. Elles compliquent la compréhension des données spécifiques attendues par votre délégué. Il n’existe aucun moyen de remplir explicitement le contexte QML à partir du QML. Si votre composant attend que des données lui soient transmises via le contexte QML, vous ne pouvez l’utiliser qu’aux endroits où le contexte approprié est mis à disposition par des moyens natifs. Il peut s’agir de votre propre code C++ ou des implémentations spécifiques des éléments environnants. À l’inverse, les propriétés obligatoires peuvent être définies de plusieurs façons depuis le QML ou par des moyens natifs. Par conséquent, le passage de données via le contexte QML réduit la réutilisabilité de vos composants.
En cas de conflit de nommage entre les propriétés du modèle et celles du délégué, il est possible d’accéder aux rôles en utilisant à la place le nom qualifié du modèle. Par exemple, si un type « Text » disposait de propriétés (non obligatoires) « type » ou « age », le texte de l’exemple ci-dessus afficherait les valeurs de ces propriétés au lieu des valeurs « type » et « age » provenant de l’élément du modèle. Dans ce cas, les propriétés auraient pu être référencées sous la forme model.type et model.age afin de garantir que le délégué affiche les valeurs des propriétés de l’élément du modèle. Pour que cela fonctionne, vous devez rendre obligatoire la propriété model dans votre délégué (à moins que vous n’utilisiez des propriétés de contexte).
Un rôle d’index spécial contenant l’index de l’élément dans le modèle est également disponible pour le délégué. Notez que cet index est défini sur -1 si l’élément est supprimé du modèle. Si vous vous liez au rôle d’index, assurez-vous que la logique tient compte de la possibilité que l’index soit égal à -1, c’est-à-dire que l’élément ne soit plus valide. (En général, l’élément sera détruit peu après, mais il est possible de retarder la destruction du délégué dans certaines vues via une propriété attachée de type « delayRemove ».)
N’oubliez pas que vous pouvez utiliser des entiers ou des tableaux comme modèle :
Repeater {
model: ["one", "two", "three"]
Text {
required property string modelData
text: modelData
}
}Ces modèles fournissent une donnée unique et anonyme à chaque instance du délégué. L'accès à cette donnée est la principale raison d'utiliser `modelData`, mais d'autres modèles fournissent également `modelData`.
L'objet fourni via le rôle « model » possède une propriété dont le nom est vide. Cette propriété anonyme contient les données « modelData ». De plus, l'objet fourni via le rôle « model » possède une autre propriété appelée « modelData ». Cette propriété est obsolète et contient également les données « modelData ».
Outre le rôle « model », un rôle « modelData » est fourni. Le rôle « modelData » contient les mêmes données que la propriété « modelData » et que la propriété anonyme de l’objet fourni via le rôle « model ».
Les différences entre le rôle « model » et les différents moyens d'accéder à « modelData » sont les suivantes :
- Les modèles qui ne possèdent pas de rôles nommés (tels que des entiers ou un tableau de chaînes de caractères) voient leurs données fournies via le rôle « modelData ». Dans ce cas, le rôle « modelData » ne contient pas nécessairement un objet. Dans le cas d’un modèle de type entier, il contiendrait un entier (l’index de l’élément actuel du modèle). Dans le cas d’un tableau de chaînes de caractères, il contiendrait une chaîne de caractères. Le rôle « model » contient toujours un objet, mais sans aucune propriété correspondant à des rôles nommés. Le modèle contient toutefois toujours ses propriétés habituelles « modelData » et « anonymous ».
- Si le modèle ne possède qu’un seul rôle nommé, le rôle modelData contient les mêmes données que le rôle nommé. Il ne s’agit pas nécessairement d’un objet et il ne contient pas le rôle nommé en tant que propriété nommée, comme ce serait habituellement le cas. Le rôle model contient toujours un objet avec le rôle nommé en tant que propriété, ainsi que les propriétés modelData et anonymes dans ce cas.
- Pour les modèles comportant plusieurs rôles, le rôle « modelData » est uniquement fourni en tant que propriété obligatoire, et non en tant que propriété de contexte. Cela est dû à la compatibilité ascendante avec les anciennes versions de Qt.
La propriété « anonymous » du modèle vous permet d’écrire proprement des délégués qui reçoivent à la fois leurs données de modèle et le nom du rôle auquel ils doivent réagir, sous forme de propriétés provenant de l’extérieur. Vous pouvez fournir un modèle sans rôle nommé, ou avec un seul rôle nommé, et une chaîne vide comme rôle. Dans ce cas, une liaison qui accède simplement à « model[role] » fonctionnera comme prévu. Vous n’avez pas besoin d’ajouter de code spécifique pour ce cas de figure.
Remarque : les rôles « model », « index » et « modelData » ne sont pas accessibles si le délégué contient des propriétés obligatoires, à moins qu’il ne dispose également de propriétés obligatoires portant des noms correspondants.
QML fournit plusieurs types de modèles de données parmi l’ensemble intégré de types QML. De plus, des modèles peuvent être créés avec Qt C++, puis mis à la disposition d’ QQmlEngine pour être utilisés par des composants QML. Pour plus d’informations sur la création de ces modèles, consultez les articles Utilisation de modèles C++ avec les vues d’ Qt Quick et Création de types QML.
Le positionnement des éléments d’un modèle peut être réalisé à l’aide d’un « Repeater ».
Modèle de liste
ListModel est une hiérarchie simple de types spécifiée en QML. Les rôles disponibles sont définis par les propriétés de l'ListElement.
ListModel {
id: fruitModel
ListElement {
name: "Apple"
cost: 2.45
}
ListElement {
name: "Orange"
cost: 3.25
}
ListElement {
name: "Banana"
cost: 1.95
}
}Le modèle ci-dessus comporte deux rôles : « name » et « cost ». Ceux-ci peuvent être liés à un délégué « ListView », par exemple :
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 fournit des méthodes permettant de manipuler directement l’ ListModel via JavaScript. Dans ce cas, le premier élément inséré détermine les rôles disponibles pour toutes les vues utilisant ce modèle. Par exemple, si un ListModel vide est créé et renseigné via JavaScript, les rôles fournis par la première insertion sont les seuls qui s’afficheront dans la vue :
ListModel { id: fruitModel }
...
MouseArea {
anchors.fill: parent
onClicked: fruitModel.append({"cost": 5.95, "name":"Pizza"})
}Lorsque l’on clique sur l’ MouseArea, fruitModel disposera de deux rôles : « cost » et « name ». Même si des rôles supplémentaires sont ajoutés par la suite, seuls les deux premiers seront pris en compte par les vues utilisant ce modèle. Pour réinitialiser les rôles disponibles dans le modèle, appelez la méthode ListModel::clear().
Modèle XML
XmlListModel permet de construire un modèle à partir d’une source de données XML. Les rôles sont spécifiés via le type ` XmlListModelRole `. Ce type doit être importé.
import QtQml.XmlListModelLe modèle suivant comporte trois rôles : title, link et 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" }
}La propriété « query » spécifie que l’ XmlListModel génère un élément de modèle pour chaque « <item> » présent dans le document XML.
La démo RSS News montre comment utiliser « XmlListModel » pour afficher un flux RSS.
Modèle d'objet
ObjectModel contient les éléments visuels à utiliser dans une vue. Lorsqu’un ObjectModel est utilisé dans une vue, celle-ci ne nécessite pas de délégué, car l’ ObjectModel contient déjà le délégué visuel (les éléments).
L'exemple ci-dessous place trois rectangles colorés dans une ListView.
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
}
}Les entiers comme modèles
Un entier peut être utilisé comme modèle contenant un certain nombre de types. Dans ce cas, le modèle ne comporte aucun rôle de données.
L'exemple suivant crée une « ListView » (séquence de nombres entiers) comportant cinq éléments :
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
}
}Remarque : le nombre d'éléments dans un modèle entier estlimité à 100 000 000.
Instances d'objets en tant que modèles
Une instance d'objet peut être utilisée pour définir un modèle comportant un seul type d'objet. Les propriétés de l'objet sont fournies sous forme de rôles.
L'exemple ci-dessous crée une liste comportant un élément, affichant la couleur du texte myText. Notez l'utilisation de la propriété model.color entièrement qualifiée afin d'éviter tout conflit avec la propriété color du type Text dans le délégué.
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
}
}Modèles de données C++
Les modèles peuvent être définis en C++ puis mis à disposition de QML. Ce mécanisme est utile pour exposer à QML des modèles de données C++ existants ou des ensembles de données complexes.
Pour plus d’informations, consultez l’article « Utilisation de modèles C++ avec les vues d’ Qt Quick ».
Modèles de tableaux
Vous pouvez utiliser des tableaux JavaScript et divers types de listes QML comme modèles. Les éléments de la liste seront mis à disposition en tant que « model » et « modelData » selon les règles décrites ci-dessus : les données simples, telles que les entiers ou les chaînes de caractères, sont mises à disposition en tant que « modelData » simple. Les données structurées, telles que les objets JavaScript ou les QObjects, sont mises à disposition en tant que « model » et « modelData » structurés.
Les rôles de modèle individuels sont également mis à disposition si vous les demandez en tant que propriétés obligatoires. Comme nous ne pouvons pas savoir à l’avance quels objets apparaîtront dans un tableau, toute propriété obligatoire d’un délégué sera renseignée, éventuellement avec une conversion d’ undefined e vers le type requis. Les rôles de modèle individuels ne sont toutefois pas mis à disposition via le contexte QML. Ils masqueraient en effet toutes les autres propriétés du contexte.
Répéteurs

Les répétiteurs créent des éléments à partir d’un modèle destiné à être utilisé avec des positionneurs, en utilisant les données d’un modèle. La combinaison de répétiteurs et de positionneurs constitue un moyen simple de disposer un grand nombre d’éléments. Un élément « Repeater » est placé à l’intérieur d’un positionneur et génère des éléments que le positionneur qui l’entoure organise.
Chaque répéteur crée un certain nombre d’éléments en combinant chaque élément de données d’un modèle, spécifié à l’aide de la propriété « model », avec l’élément modèle, défini comme un élément enfant au sein du répéteur. Le nombre total d’éléments est déterminé par la quantité de données contenues dans le modèle.
L’exemple suivant montre un Repeater utilisé avec un élément Grid pour agencer un ensemble d’éléments Rectangle. L’élément Repeater crée une série de 24 rectangles que l’élément Grid positionne selon une disposition 5 × 5.
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
}
}
}
}
}Le nombre d’éléments créés par un Repeater est déterminé par sa propriété count. Il n’est pas possible de définir cette propriété pour déterminer le nombre d’éléments à créer. À la place, comme dans l’exemple ci-dessus, on utilise un entier comme modèle.
Pour plus de détails, consultez le document « Modèles de données QML ».
Si le modèle est une liste de chaînes de caractères, le délégué donne également accès à la propriété modelData habituelle, en lecture seule, qui contient la chaîne. Par exemple :
|
Il est également possible d'utiliser un délégué comme modèle pour les éléments créés par un Repeater. Cela se spécifie à l'aide de la propriété delegate.
Modification des données du modèle
Toutes les vues concernées disposent d'une propriété appelée `delegateModelAccess ` qui détermine si et comment vous pouvez modifier les données du modèle à partir du délégué. Dans la plupart des cas, vous devez la définir sur `DelegateModel.ReadWrite`. Cela permettra à votre délégué de modifier les données du modèle de la manière la plus flexible possible. Vous pouvez également la définir sur ` DelegateModel.ReadOnly` si vous ne souhaitez pas que le délégué modifie les données du modèle.
Le tableau suivant décrit en détail toutes les valeurs que la propriété peut prendre.
| DelegateModel.Qt5ReadWrite | Le délégué peut attribuer des valeurs à n’importe quelle propriété de contexte fournie par la vue afin de modifier l’élément de modèle concerné. De plus, il peut également attribuer des valeurs aux propriétés de l’objet ` model `, qu’il s’agisse de propriétés de contexte ou de propriétés obligatoires, dans le même but. Le délégué ne peut toutefois pas modifier les données du modèle en attribuant des valeurs aux propriétés obligatoires renseignées par la vue. Si vous attribuez une valeur à une propriété obligatoire d’un délégué, la liaison qui met à jour cette propriété à partir des données du modèle est rompue. La propriété obligatoire conserve alors la valeur que vous lui avez attribuée, même si le modèle venait à changer par la suite. DelegateModel.Qt5ReadWrite est la valeur par défaut de delegateModelAccess. |
| DelegateModel.ReadOnly | Le délégué ne peut pas attribuer de valeurs aux propriétés de contexte fournies par la vue, ni aux propriétés de l’objet ` model `. L’attribution d’une valeur à une propriété obligatoire renseignée par la vue ne rompt pas la liaison interne et ne modifie pas non plus les données du modèle. La propriété obligatoire conservera la valeur qui lui a été attribuée jusqu’à ce que l’élément du modèle change à nouveau. |
| DelegateModel.ReadWrite | Le délégué peut attribuer des valeurs à n’importe quelle propriété de contexte fournie par la vue afin de modifier l’élément de modèle concerné. De plus, il peut également attribuer des valeurs aux propriétés de l’objet ` model `, qu’il s’agisse d’une propriété de contexte ou d’une propriété obligatoire, avec le même effet. Le délégué peut également modifier les données du modèle en attribuant des valeurs aux propriétés obligatoires renseignées par la vue. L’attribution d’une valeur à une propriété obligatoire propage cette valeur à l’élément de modèle correspondant sans rompre les liaisons internes. |
Certains modèles sont des objets dotés d’identités indépendantes auxquels la vue fait référence. L’objet d’origine est la seule source de vérité pour la création de délégués. Il n’est pas copié. Ces modèles seront visiblement mis à jour lors de l’écriture via les délégués.
D'autres modèles ne possèdent pas d'identité indépendante et sont copiés lorsqu'ils sont attribués à la vue. Pour ces modèles, seules les données internes de la vue sont mises à jour lors de l'écriture via le délégué. Le modèle d'origine reste inchangé.
En général, les types d’objets QML possèdent une identité indépendante, contrairement aux types de valeurs QML. Ainsi, ListModel, tout ce qui dérive de QAbstractItemModel, ainsi qu’une instance unique d’un type d’objet ou une liste d’instances de types d’objets, seront mis à jour lorsqu’ils sont transmis en tant que modèle et modifiés via le délégué. En revanche, les tableaux JavaScript, les listes de types de valeurs ou les nombres simples ne sont pas mis à jour lorsque vous modifiez les données du modèle via le délégué.
De plus, lorsque vous implémentez votre propre modèle C++, vous devez implémenter la méthode ` setData ` pour recevoir les mises à jour transmises par les délégués.
Supposons qu’un modèle C++ basé sur ` QAbstractItemModel ` et implémentant la méthode ` setData ` soit enregistré en tant que type QML nommé ` EditableModel`. Les données pourraient alors être écrites dans le modèle comme suit :
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
}
}Vous pouvez également modifier les données du modèle en manipulant l’objet ` model ` de la manière suivante :
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
}
}Remarque : le rôle « edit » correspond à « Qt::EditRole ». Consultez roleNames() pour connaître les noms des rôles intégrés. Cependant, dans la pratique, les modèles enregistrent généralement des rôles personnalisés.
Pour plus d’informations, consultez l’article « Utilisation de modèles C++ avec les vues d’ Qt Quick ».
Utilisation des transitions
Les transitions permettent d'animer les éléments ajoutés à un positionneur, déplacés à l'intérieur de celui-ci ou supprimés de celui-ci.
Les transitions d’ajout s’appliquent aux éléments créés dans le cadre d’un positionneur, ainsi qu’à ceux qui sont rattachés à celui-ci pour devenir ses enfants.
Les transitions de suppression s'appliquent aux éléments situés à l'intérieur d'un positionneur qui sont supprimés, ainsi qu'à ceux qui sont retirés d'un positionneur et auxquels on attribue de nouveaux parents dans un document.
Remarque : le fait de régler l’opacité des éléments sur zéro ne les fait pas disparaître du positionneur. Ils peuvent être supprimés puis rajoutés en modifiant la propriété « visible ».
© 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.
