Utilisation de modèles C++ avec Qt Quick Views
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 permet d'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 en tant que QStringList, QVariantList, QObjectList ou QAbstractItemModel. Les trois premières sont utiles pour exposer des ensembles de données plus simples, tandis que QAbstractItemModel fournit une solution plus flexible pour des modèles plus complexes.
Modèle basé sur une liste de chaînes de caractères
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 Qtml peut charger ce document QML et définir la valeur de myModel en 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 examples/quick/models/stringlistmodel dans le répertoire d'installation de Qt.
Remarque : la vue n'a aucun moyen de savoir que le contenu de QStringList a changé. Si le contenu de 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 une liste de variables
Un modèle peut être un simple QVariantList, qui fournit le contenu de la liste via le rôle modelData.
L'API fonctionne de la même manière que pour QStringList, comme indiqué dans la section précédente.
Remarque : la vue n'a aucun moyen de savoir que le contenu d'un site QVariantList a changé. Si le contenu de 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 une liste d'objets Q
Une liste de valeurs QObject* peut également être utilisée comme modèle. Un QList<QObject*> fournit les propriétés des objets de la liste en tant que 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<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) }}); ...
La valeur QObject* est disponible en tant que propriété modelData. Par commodité, les propriétés de l'objet sont également disponibles directement dans le contexte du délégué. Ici, view.qml fait référence aux propriétés de DataModel dans le 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 des propriétés existantes en les déclarant comme required dans un type dérivé.
Le code source complet de cet exemple est disponible dans examples/quick/models/objectlistmodel dans le répertoire d'installation de Qt Quick.
Remarque : la vue n'a aucun moyen de savoir que le contenu de QObjectList a changé. Si le contenu de 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 sous-classant QAbstractItemModel. C'est la meilleure approche si vous avez un modèle plus complexe qui ne peut pas être pris en charge par les autres approches. Une sous-classe QAbstractItemModel peut également notifier automatiquement une vue QML lorsque les données du modèle sont modifiées.
Les rôles d'une sous-classe QAbstractItemModel peuvent être exposés à QML en réimplémentant QAbstractItemModel::roleNames().
Voici une application avec une sous-classe QAbstractListModel nommée AnimalModel, qui expose les rôles de type et de taille. Elle réimplémente QAbstractItemModel::roleNames() pour exposer les noms des 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 de type et de taille:
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 suivre les règles standard pour les changements de modèle et notifier la vue lorsque le modèle a changé en utilisant QAbstractItemModel::dataChanged(), QAbstractItemModel::beginInsertRows(), et ainsi de suite. Pour plus d'informations, voir la référence sur la sous-classe de modèle.
Le code source complet de cet exemple est disponible dans examples/quick/models/abstractitemmodel dans le répertoire d'installation de Qt Quick.
QAbstractItemModel L'interface QML présente une hiérarchie de tableaux, mais les vues actuellement fournies par QML ne peuvent afficher que des données sous forme de liste. Pour 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:
- hasModelChildren propriété de rôle permettant de déterminer si un nœud a 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 qui peut être affecté à DelegateModel::rootIndex
Exposition des modèles de données C++ à QML
Les exemples ci-dessus utilisent les propriétés requises de la vue pour définir les valeurs du modèle directement dans les composants QML. Une autre solution consiste à enregistrer la classe de modèle C++ en tant que type QML (voir Définir des types QML à partir de C++). Les classes de modèle peuvent ainsi être créées directement en tant que types dans QML :
| C++ | class MyModel : public QAbstractItemModel { Q_OBJECT QML_ELEMENT // [...] } |
| QML | MyModel { id: myModel } |
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 méthodes roleNames() et data(), les modèles modifiables doivent réimplémenter la méthode setData pour enregistrer les modifications apportées aux données du modèle existant. La version suivante de la méthode vérifie si l'index du modèle donné 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 s'avère nécessaire. Pour ce faire, il suffit d'attribuer une nouvelle valeur à la propriété de 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 égal à Qt::EditRole. Voir roleNames() pour les noms de rôles intégrés. Toutefois, les modèles réels 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.