Utilisation de modèles C++ avec les vues d'Qt Quick
Données fournies dans un modèle C++ personnalisé
Les modèles peuvent être définis en C++ puis mis à la disposition de QML. Cela est utile pour exposer à QML des modèles de données C++ existants ou des ensembles de données complexes.
Une classe de modèle C++ peut être définie comme un ` QStringList`, un ` QVariantList`, un ` QObjectList ` ou un ` QAbstractItemModel`. Les trois premières sont utiles pour exposer des ensembles de données plus simples, tandis que ` QAbstractItemModel ` offre une solution plus flexible pour les modèles plus complexes.
Modèle basé sur QStringList
Un modèle peut être un simple « QStringList », qui fournit le contenu de la liste via le rôle modelData.
Voici un ListView avec un délégué qui fait référence à la valeur de son élément de modèle à l’aide du rôle modelData:
ListView {
width: 100
height: 100
required model
delegate: Rectangle {
required property string modelData
height: 25
width: 100
Text { text: parent.modelData }
}
}Une application Qt peut charger ce document QML et définir la valeur de ` myModel ` sur un ` QStringList` :
QStringList dataList = {
"Item 1",
"Item 2",
"Item 3",
"Item 4"
};
QQuickView view;
view.setInitialProperties({{ "model", QVariant::fromValue(dataList) }});Le code source complet de cet exemple est disponible dans le répertoire examples/quick/models/stringlistmodel du répertoire d'installation de Qt.
Remarque : la vuen’a aucun moyen de savoir que le contenu d’une ` QStringList ` a changé. Si l’ QStringList change, il sera nécessaire de réinitialiser le modèle en définissant à nouveau la propriété ` model ` de la vue.
Modèle basé sur QVariantList
Un modèle peut être une seule instance de ` QVariantList`, qui fournit le contenu de la liste via le rôle `modelData `.
L’API fonctionne exactement comme avec QStringList, comme indiqué dans la section précédente.
Remarque : la vuen’a aucun moyen de savoir si le contenu d’un ` QVariantList ` a changé. Si l’ QVariantList change, il sera nécessaire de réinitialiser le modèle en définissant à nouveau la propriété ` model ` de la vue.
Modèle basé sur QObjectList
Une liste de valeurs de type QObject* peut également servir de modèle. Un QList<QObject*> fournit les propriétés des objets de la liste sous forme de rôles.
L'application suivante crée une classe ` DataObject ` avec des valeurs ` Q_PROPERTY ` qui seront accessibles en tant que rôles nommés lorsqu'un ` QList` de type `<DataObject*>` est exposé à QML :
class DataObject : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
...
};
int main(int argc, char ** argv)
{
QGuiApplication app(argc, argv);
const QStringList colorList = {"red",
"green",
"blue",
"yellow"};
const QStringList moduleList = {"Core", "GUI", "Multimedia", "Multimedia Widgets", "Network",
"QML", "Quick", "Quick Controls", "Quick Dialogs",
"Quick Layouts", "Quick Test", "SQL", "Widgets", "3D",
"Android Extras", "Bluetooth", "Concurrent", "D-Bus",
"Gamepad", "Graphical Effects", "Help", "Image Formats",
"Location", "Mac Extras", "NFC", "OpenGL", "Platform Headers",
"Positioning", "Print Support", "Purchasing", "Quick Extras",
"Quick Timeline", "Quick Widgets", "Remote Objects", "Script",
"SCXML", "Script Tools", "Sensors", "Serial Bus",
"Serial Port", "Speech", "SVG", "UI Tools", "WebEngine",
"WebSockets", "WebView", "Windows Extras", "XML",
"XML Patterns", "Charts", "Network Authorization",
"Virtual Keyboard", "Quick 3D", "Quick WebGL"};
QList<QObject *> dataList;
for (const QString &module : moduleList)
dataList.append(new DataObject("Qt " + module, colorList.at(rand() % colorList.length())));
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setInitialProperties({{ "model", QVariant::fromValue(dataList) }});
...L’ QObject* est disponible via la propriété modelData. Pour plus de commodité, les propriétés de l’objet sont également directement accessibles dans le contexte du délégué. Ici, view.qml fait référence aux propriétés DataModel du délégué ListView:
ListView {
id: listview
width: 200; height: 320
required model
ScrollBar.vertical: ScrollBar { }
delegate: Rectangle {
width: listview.width; height: 25
required color
required property string name
Text { text: parent.name }
}
}Notez l'utilisation de la propriété color. Vous pouvez exiger l'existence de propriétés en les déclarant comme required dans un type dérivé.
Le code source complet de cet exemple est disponible dans le répertoire examples/quick/models/objectlistmodel du répertoire d’installation de Qt.
Remarque : la vuen'a aucun moyen de savoir que le contenu d’un ` QObjectList ` a changé. Si l’ QObjectList change, il sera nécessaire de réinitialiser le modèle en définissant à nouveau la propriété ` model ` de la vue.
Sous-classe de QAbstractItemModel
Un modèle peut être défini en créant une sous-classe de ` QAbstractItemModel`. C’est la meilleure approche si vous disposez d’un modèle plus complexe qui ne peut pas être pris en charge par les autres approches. Un ` QAbstractItemModel ` peut également notifier automatiquement une vue QML lorsque les données du modèle changent.
Les rôles d’une sous-classe de ` QAbstractItemModel ` peuvent être exposés au QML en réimplémentant la méthode ` QAbstractItemModel::roleNames()`.
Voici une application comportant une sous-classe de ` QAbstractListModel ` nommée ` AnimalModel`, qui expose les rôles `type ` et `sizes`. Elle réimplémente la méthode ` QAbstractItemModel::roleNames()` pour exposer les noms de rôles, afin qu’ils soient accessibles via QML :
class Animal
{
public:
Animal(const QString &type, const QString &size);
...
};
class AnimalModel : public QAbstractListModel
{
Q_OBJECT
public:
enum AnimalRoles {
TypeRole = Qt::UserRole + 1,
SizeRole
};
AnimalModel(QObject *parent = nullptr);
...
};
QHash<int, QByteArray> AnimalModel::roleNames() const {
QHash<int, QByteArray> roles;
roles[TypeRole] = "type";
roles[SizeRole] = "size";
return roles;
}
int main(int argc, char ** argv)
{
QGuiApplication app(argc, argv);
AnimalModel model;
model.addAnimal(Animal("Wolf", "Medium"));
model.addAnimal(Animal("Polar bear", "Large"));
model.addAnimal(Animal("Quoll", "Small"));
QQuickView view;
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.setInitialProperties({{"model", QVariant::fromValue(&model)}});
...Ce modèle est affiché par un délégué « ListView » qui accède aux rôles « type » et « size » :
ListView {
width: 200; height: 250
required model
delegate: Text {
required property string type
required property string size
text: "Animal: " + type + ", " + size
}
}Les vues QML sont automatiquement mises à jour lorsque le modèle change. N'oubliez pas que le modèle doit respecter les règles standard relatives aux modifications de modèle et notifier la vue lorsque le modèle a changé en utilisant QAbstractItemModel::dataChanged(), QAbstractItemModel::beginInsertRows(), etc. Consultez la référence sur la sous-classification des modèles pour plus d'informations.
Le code source complet de cet exemple est disponible dans le répertoire examples/quick/models/abstractitemmodel du répertoire d'installation de Qt.
QAbstractItemModel présente une hiérarchie de tables, mais les vues actuellement fournies par QML ne peuvent afficher que des données sous forme de liste. Afin d’afficher les listes d’enfants d’un modèle hiérarchique, utilisez le type QML ` DelegateModel `, qui fournit les propriétés et fonctions suivantes à utiliser avec les modèles de liste de type ` QAbstractItemModel ` :
- propriété de rôle`hasModelChildren ` pour déterminer si un nœud possède des nœuds enfants.
- DelegateModel::rootIndex permet de spécifier le nœud racine
- DelegateModel::modelIndex() renvoie un ` QModelIndex ` qui peut être assigné à DelegateModel::rootIndex
- DelegateModel::parentModelIndex() renvoie un ` QModelIndex ` pouvant être affecté à DelegateModel::rootIndex
Exposition des modèles de données C++ à QML
Les exemples ci-dessus utilisent des propriétés obligatoires de la vue pour définir directement les valeurs du modèle dans les composants QML. Une alternative consiste à enregistrer la classe de modèle C++ en tant que type QML (voir Définition de types QML à partir de C++). Cela permet de créer directement les classes de modèle en tant que types au sein de QML :
| C++ | |
| QML | |
Voir Écrire des extensions QML avec C++ pour plus de détails sur l'écriture de types QML en C++.
Modification des données du modèle
Outre les signaux ` roleNames() ` et ` data()`, les modèles modifiables doivent réimplémenter la méthode ` setData ` pour enregistrer les modifications apportées aux données existantes du modèle. La version suivante de cette méthode vérifie si l’index du modèle fourni est valide et si ` role ` est égal à ` Qt::EditRole` :
bool EditableModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == Qt::EditRole) {
// Set data in model here. It can also be a good idea to check whether
// the new value actually differs from the current value
if (m_entries[index.row()] != value.toString()) {
m_entries[index.row()] = value.toString();
emit dataChanged(index, index, { Qt::EditRole, Qt::DisplayRole });
return true;
}
}
return false;
}Remarque : il est important d’émettre le signal dataChanged() après avoir enregistré les modifications.
Contrairement aux vues d’éléments C++ telles que ` QListView ` ou ` QTableView`, la méthode ` setData() ` doit être explicitement invoquée à partir des délégués QML lorsque cela est nécessaire. Pour ce faire, il suffit d’attribuer une nouvelle valeur à la propriété du modèle correspondante.
ListView {
anchors.fill: parent
model: EditableModel {}
delegate: TextField {
width: ListView.view.width
text: model.edit
onAccepted: model.edit = text
}
}Remarque : le rôle edit est équivalent à Qt::EditRole. Voir roleNames() pour les noms de rôles intégrés. Cependant, dans la pratique, les modèles enregistrent généralement des rôles personnalisés.
© 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.