1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
5\page qtquick-modelviewsdata-cppmodels.html
6\title Using C++ Models with Qt Quick Views
7\brief using Qt Quick views with models defined in C++
10\section1 Data Provided In A Custom C++ Model
12Models can be defined in C++ and then made available to QML. This is useful
13for exposing existing C++ data models or otherwise complex datasets to QML.
15A C++ model class can be defined as a \l QStringList, a \l {QVariant::}{QVariantList}, a
16QObjectList or a \l QAbstractItemModel. The first three are useful for exposing
17simpler datasets, while QAbstractItemModel provides a more flexible solution for
20Here is a video tutorial that takes you through the whole process of exposing a C++
25\section2 QStringList-based Model
27A model may be a simple \l QStringList, which provides the contents of the list
28via the \e modelData role.
30Here is a ListView with a delegate that references its model item's
31value using the \c modelData role:
33\snippet models/stringlistmodel/view.qml 0
35A Qt application can load this QML document and set the value of \c myModel
38\snippet models/stringlistmodel/main.cpp 0
40The complete source code for this example is available in
41\l {models/stringlistmodel}{examples/quick/models/stringlistmodel}
42within the Qt install directory.
44\note There is no way for the view to know that the contents of a QStringList
45have changed. If the QStringList changes, it will be necessary to reset
46the model by setting the view's \c model property again.
48\section2 QVariantList-based Model
50A model may be a single \l {QVariant::}{QVariantList}, which provides the contents
51of the list via the \e modelData role.
53The API works just like with \l QStringList, as shown in the previous section.
55\note There is no way for the view to know that the contents of a QVariantList
56have changed. If the QVariantList changes, it will be necessary to reset
59\section2 QObjectList-based Model
61A list of QObject* values can also be used as a model. A QList<QObject*> provides
62the properties of the objects in the list as roles.
64The following application creates a \c DataObject class with
65Q_PROPERTY values that will be accessible as named roles when a
66QList<DataObject*> is exposed to QML:
68\snippet models/objectlistmodel/dataobject.h 0
70\snippet models/objectlistmodel/dataobject.h 1
72\snippet models/objectlistmodel/main.cpp 0
75The QObject* is available as the \c modelData property. As a convenience,
76the properties of the object are also made available directly in the
77delegate's context. Here, \c view.qml references the \c DataModel properties in
80\snippet models/objectlistmodel/view.qml 0
82Note the use of the \c color property. You can require existing properties
83by declaring them as \c required in a derived type.
85The complete source code for this example is available in
86\l {models/objectlistmodel}{examples/quick/models/objectlistmodel}
87within the Qt install directory.
89Note: There is no way for the view to know that the contents of a QList
90has changed. If the QList changes, it is necessary to reset
91the model by setting the \c model property again.
94\section2 QAbstractItemModel Subclass
96A model can be defined by subclassing QAbstractItemModel. This is the
97best approach if you have a more complex model that cannot be supported
98by the other approaches. A QAbstractItemModel can also automatically
99notify a QML view when the model data changes.
101The roles of a QAbstractItemModel subclass can be exposed to QML by
102reimplementing QAbstractItemModel::roleNames().
104Here is an application with a QAbstractListModel subclass named \c AnimalModel,
105which exposes the \e type and \e sizes roles. It reimplements
106QAbstractItemModel::roleNames() to expose the role names, so that they can be
109\snippet models/abstractitemmodel/model.h 0
111\snippet models/abstractitemmodel/model.h 1
113\snippet models/abstractitemmodel/model.h 2
115\snippet models/abstractitemmodel/model.cpp 0
117\snippet models/abstractitemmodel/main.cpp 0
120This model is displayed by a ListView delegate that accesses the \e type and \e size
123\snippet models/abstractitemmodel/view.qml 0
125QML views are automatically updated when the model changes. Remember the model
126must follow the standard rules for model changes and notify the view when
127the model has changed by using QAbstractItemModel::dataChanged(),
128QAbstractItemModel::beginInsertRows(), and so on. See the \l {Model subclassing reference} for
131The complete source code for this example is available in
132\l {models/abstractitemmodel}{examples/quick/models/abstractitemmodel}
133within the Qt install directory.
135QAbstractItemModel presents a hierarchy of tables, but the views currently provided by QML
136can only display list data.
137In order to display the child lists of a hierarchical model,
138use the DelegateModel QML type, which provides the following properties and functions to be used
139with list models of QAbstractItemModel type:
142\li \e hasModelChildren role property to determine whether a node has child nodes.
143\li \l DelegateModel::rootIndex allows the root node to be specified
144\li \l DelegateModel::modelIndex() returns a QModelIndex which can be assigned to DelegateModel::rootIndex
145\li \l DelegateModel::parentModelIndex() returns a QModelIndex which can be assigned to DelegateModel::rootIndex
150Qt provides C++ classes that support SQL data models. These classes work
151transparently on the underlying SQL data, reducing the need to run SQL
152queries for basic SQL operations such as create, insert, or update.
153For more details about these classes, see \l{Using the SQL Model Classes}.
155Although the C++ classes provide complete feature sets to operate on SQL
156data, they do not provide data access to QML. So you must implement a
157C++ custom data model as a subclass of one of these classes, and expose it
158to QML either as a type or context property.
160\section3 Read-only Data Model
162The custom model must reimplement the following methods to enable read-only
163access to the data from QML:
166\li \l{QAbstractItemModel::}{roleNames}() to expose the role names to the
167 QML frontend. For example, the following version returns the selected
168 table's field names as role names:
170 QHash<int, QByteArray> SqlQueryModel::roleNames() const
172 QHash<int, QByteArray> roles;
173 // record() returns an empty QSqlRecord
174 for (int i = 0; i < this->record().count(); i ++) {
175 roles.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8());
180\li \l{QSqlQueryModel::}{data}() to expose SQL data to the QML frontend.
181 For example, the following implementation returns data for the given
184 QVariant SqlQueryModel::data(const QModelIndex &index, int role) const
188 if (index.isValid()) {
189 if (role < Qt::UserRole) {
190 value = QSqlQueryModel::data(index, role);
192 int columnIdx = role - Qt::UserRole - 1;
193 QModelIndex modelIndex = this->index(index.row(), columnIdx);
194 value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
202The QSqlQueryModel class is good enough to implement a custom read-only
203model that represents data in an SQL database. The
204\l{Qt Quick Controls - Chat Tutorial}{chat tutorial} example
205demonstrates this very well by implementing a custom model to fetch the
206contact details from an SQLite database.
208\section3 Editable Data Model
210QSqlTableModel implements setData() as described \l{#changing-model-data}{below}.
212Depending on the \l{QSqlTableModel::}{EditStrategy} used by the model, the
213changes are either queued for submission later or submitted immediately.
215You can also insert new data into the model by calling
216\l {QSqlTableModel::insertRecord}(). In the following example snippet,
217a QSqlRecord is populated with book details and appended to the
222 QSqlRecord newRecord = record();
223 newRecord.setValue("author", "John Grisham");
224 newRecord.setValue("booktitle", "The Litigators");
225 insertRecord(rowCount(), newRecord);
229\section2 Exposing C++ Data Models to QML
231The above examples use required properties on the view to set
232model values directly in QML components. An alternative to this is to
233register the C++ model class as a QML type (see
234\l{Defining QML Types from C++}). This allows the model classes to be
235created directly as types within QML:
243class MyModel : public QAbstractItemModel
262 width: 200; height: 250
265 required property string someProperty
273See \l {Writing QML Extensions with C++} for details on writing QML types
276\section2 Changing Model Data
278Besides the \c roleNames() and \c data(), editable models must reimplement
279the \l{QAbstractItemModel::}{setData} method to save changes to existing model data.
280The following version of the method checks if the given model index is valid
281and the \c role is equal to \l Qt::EditRole:
284bool EditableModel::setData(const QModelIndex &index, const QVariant &value, int role)
286 if (index.isValid() && role == Qt::EditRole) {
287 // Set data in model here. It can also be a good idea to check whether
288 // the new value actually differs from the current value
289 if (m_entries[index.row()] != value.toString()) {
290 m_entries[index.row()] = value.toString();
291 emit dataChanged(index, index, { Qt::EditRole, Qt::DisplayRole });
299\note It is important to emit the \l{QAbstractItemModel::}{dataChanged}()
300signal after saving the changes.
302Unlike the C++ item views such as QListView or QTableView, the \c setData()
303method must be explicitly invoked from QML delegates whenever appropriate. This is done
304by simply assigning a new value to the corresponding model property.
309 model: EditableModel {}
310 delegate: TextField {
311 width: ListView.view.width
313 onAccepted: model.edit = text
318\note The \c edit role is equal to \l Qt::EditRole. See \l{QAbstractItemModel::}{roleNames}()
319for the built-in role names. However, real life models would usually register custom roles.