Verwendung von C++-Modellen mit Ansichten in „ Qt Quick “
Daten, die in einem benutzerdefinierten C++-Modell bereitgestellt werden
Modelle können in C++ definiert und anschließend für QML bereitgestellt werden. Dies ist nützlich, um bestehende C++-Datenmodelle oder anderweitig komplexe Datensätze für QML zugänglich zu machen.
Eine C++-Modellklasse kann als ` QStringList`, ` QVariantList`, ` QObjectList ` oder ` QAbstractItemModel` definiert werden. Die ersten drei eignen sich für einfachere Datensätze, während ` QAbstractItemModel ` eine flexiblere Lösung für komplexere Modelle bietet.
QStringList-basiertes Modell
Ein Modell kann ein einfaches ` QStringList` sein, das den Inhalt der Liste über die Rolle `modelData ` bereitstellt.
Hier ist ein ` ListView ` mit einem Delegaten, der über die Rolle ` modelData ` auf den Wert seines Modellelements verweist:
ListView {
width: 100
height: 100
required model
delegate: Rectangle {
required property string modelData
height: 25
width: 100
Text { text: parent.modelData }
}
}Eine Qt-Anwendung kann dieses QML-Dokument laden und den Wert von ` myModel ` auf ` QStringList` setzen:
QStringList dataList = {
"Item 1",
"Item 2",
"Item 3",
"Item 4"
};
QQuickView view;
view.setInitialProperties({{ "model", QVariant::fromValue(dataList) }});Der vollständige Quellcode für dieses Beispiel ist im Verzeichnis „examples/quick/models/stringlistmodel“ im Qt-Installationsverzeichnis verfügbar.
Hinweis: Die Ansichthat keine Möglichkeit zu erkennen, dass sich der Inhalt eines ` QStringList ` geändert hat. Wenn sich das ` QStringList ` ändert, muss das Modell zurückgesetzt werden, indem die Eigenschaft ` model ` der Ansicht erneut gesetzt wird.
QVariantList-basiertes Modell
Ein Modell kann ein einzelnes ` QVariantList` sein, das den Inhalt der Liste über die Rolle `modelData ` bereitstellt.
Die API funktioniert genau wie bei „ QStringList “, wie im vorherigen Abschnitt gezeigt.
Hinweis: Die Ansichthat keine Möglichkeit zu erkennen, dass sich der Inhalt eines „ QVariantList “ geändert hat. Wenn sich die „ QVariantList “ ändert, muss das Modell zurückgesetzt werden, indem die Eigenschaft „ model “ der Ansicht erneut gesetzt wird.
QObjectList-basiertes Modell
Eine Liste von QObject*-Werten kann ebenfalls als Modell verwendet werden. Ein QList<QObject*> stellt die Eigenschaften der Objekte in der Liste als Rollen bereit.
Die folgende Anwendung erstellt eine „ DataObject “-Klasse mit „ Q_PROPERTY “-Werten, auf die als benannte Rollen zugegriffen werden kann, wenn ein „ QList<DataObject*>“ für QML freigegeben wird:
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) }});
...QObject* ist als Eigenschaft „ modelData “ verfügbar. Der Einfachheit halber werden die Eigenschaften des Objekts auch direkt im Kontext des Delegaten bereitgestellt. Hier verweist view.qml auf die Eigenschaften „ DataModel “ im Delegaten „ 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 }
}
}Beachten Sie die Verwendung der Eigenschaft ` color `. Sie können vorhandene Eigenschaften erzwingen, indem Sie sie in einem abgeleiteten Typ als ` required ` deklarieren.
Der vollständige Quellcode für dieses Beispiel ist im Verzeichnis „examples/quick/models/objectlistmodel“ im Qt-Installationsverzeichnis verfügbar.
Hinweis: Die Ansichthat keine Möglichkeit zu erkennen, dass sich der Inhalt eines „ QObjectList “ geändert hat. Wenn sich das „ QObjectList “ ändert, muss das Modell zurückgesetzt werden, indem die Eigenschaft „ model “ der Ansicht erneut gesetzt wird.
Unterklasse von `QAbstractItemModel`
Ein Modell kann durch eine Unterklasse von ` QAbstractItemModel` definiert werden. Dies ist der beste Ansatz, wenn Sie ein komplexeres Modell haben, das mit den anderen Ansätzen nicht unterstützt werden kann. Ein ` QAbstractItemModel ` kann eine QML-Ansicht auch automatisch benachrichtigen, wenn sich die Modelldaten ändern.
Die Rollen einer QAbstractItemModel -Unterklasse können für QML verfügbar gemacht werden, indem QAbstractItemModel::roleNames() neu implementiert wird.
Hier ist eine Anwendung mit einer Unterklasse von „ QAbstractListModel “ namens „ AnimalModel “, die die Rollen „type“ und „sizes“ verfügbar macht. Sie implementiert „ QAbstractItemModel::roleNames()“ neu, um die Rollennamen verfügbar zu machen, sodass über QML darauf zugegriffen werden kann:
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)}});
...Dieses Modell wird von einem „ ListView “-Delegaten dargestellt, der auf die Rollen „type“ und „size“ zugreift:
ListView {
width: 200; height: 250
required model
delegate: Text {
required property string type
required property string size
text: "Animal: " + type + ", " + size
}
}QML-Ansichten werden automatisch aktualisiert, wenn sich das Modell ändert. Beachten Sie, dass das Modell die Standardregeln für Modelländerungen befolgen und die Ansicht über „ QAbstractItemModel::dataChanged()“, „ QAbstractItemModel::beginInsertRows()“ usw. benachrichtigen muss, wenn sich das Modell geändert hat. Weitere Informationen finden Sie in der Referenz zur Unterklassifizierung von Modellen.
Der vollständige Quellcode für dieses Beispiel ist im Verzeichnis „examples/quick/models/abstractitemmodel“ im Qt-Installationsverzeichnis verfügbar.
QAbstractItemModel stellt eine Hierarchie von Tabellen dar, doch die derzeit von QML bereitgestellten Ansichten können nur Listendaten anzeigen. Um die untergeordneten Listen eines hierarchischen Modells anzuzeigen, verwenden Sie den QML-Typ „ DelegateModel “, der die folgenden Eigenschaften und Funktionen zur Verwendung mit Listenmodellen vom Typ „ QAbstractItemModel “ bereitstellt:
- Die Rolleigenschaft `hasModelChildren ` dient dazu, festzustellen, ob ein Knoten untergeordnete Knoten hat.
- DelegateModel::rootIndex ermöglicht die Angabe des Stammknotens
- DelegateModel::modelIndex() gibt ein ` QModelIndex ` zurück, das zugewiesen werden kann DelegateModel::rootIndex
- DelegateModel::parentModelIndex() gibt ein ` QModelIndex ` zurück, das zugewiesen werden kann DelegateModel::rootIndex
Bereitstellung von C++-Datenmodellen für QML
In den obigen Beispielen werden erforderliche Eigenschaften der Ansicht verwendet, um Modellwerte direkt in QML-Komponenten festzulegen. Eine Alternative dazu ist die Registrierung der C++-Modellklasse als QML-Typ (siehe „Definieren von QML-Typen aus C++“). Dadurch können die Modellklassen direkt als Typen innerhalb von QML erstellt werden:
| C++ | |
| QML | |
Weitere Informationen zum Schreiben von QML-Typen in C++ finden Sie unter „QML-Erweiterungen mit C++ schreiben “.
Ändern von Modelldaten
Neben den Signalen „ roleNames() “ und „ data() “ müssen bearbeitbare Modelle die Methode „ setData “ neu implementieren, um Änderungen an bestehenden Modelldaten zu speichern. Die folgende Version der Methode prüft, ob der angegebene Modellindex gültig ist und ob „ role “ gleich „ Qt::EditRole “ ist:
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;
}Hinweis: Es ist wichtig, nach dem Speichern der Änderungen das Signal „ dataChanged()“ auszulösen.
Im Gegensatz zu den C++-Item-Ansichten wie „ QListView “ oder „ QTableView “ muss die Methode „ setData() “ bei Bedarf explizit über QML-Delegaten aufgerufen werden. Dies geschieht durch einfache Zuweisung eines neuen Werts an die entsprechende Modelleigenschaft.
ListView {
anchors.fill: parent
model: EditableModel {}
delegate: TextField {
width: ListView.view.width
text: model.edit
onAccepted: model.edit = text
}
}Hinweis: Die Rolle „ edit “ entspricht „ Qt::EditRole “. Die integrierten Rollennamen finden Sie unter „ roleNames()“. In der Praxis würden Modelle jedoch in der Regel benutzerdefinierte Rollen registrieren.
© 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.