diff options
author | Venugopal Shivashankar <venugopal.shivashankar@digia.com> | 2016-03-01 15:31:52 +0100 |
---|---|---|
committer | Venugopal Shivashankar <Venugopal.Shivashankar@qt.io> | 2016-07-28 14:38:11 +0000 |
commit | 75d6392d6c5efa6fdd1f63cac6a2438fedb2f2a9 (patch) | |
tree | b1b9018e3064e9067cd118d297dcefbdfd6937ca /src/quick | |
parent | 3c9a70eec93ad3155708686b4aa8493599341a6b (diff) |
Doc: Describe how to implement custom SQL models for QML
Change-Id: I31781f32c2f9699f386a326f18cb5cc705582a89
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc b/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc index cb281a2d4a..a764402c2f 100644 --- a/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc +++ b/src/quick/doc/src/concepts/modelviewsdata/cppmodels.qdoc @@ -156,6 +156,111 @@ with list models of QAbstractItemModel type: \li \l DelegateModel::parentModelIndex() returns a QModelIndex which can be assigned to DelegateModel::rootIndex \endlist +\section2 SQL Models + +Qt provides C++ classes that support SQL data models. These classes work +transparently on the underlying SQL data, reducing the need to run SQL +queries for basic SQL operations such as create, insert, or update. +For more details about these classes, see \l{Using the SQL Model Classes}. + +Although the C++ classes provide complete feature sets to operate on SQL +data, they do not provide data access to QML. So you must implement a +C++ custom data model as a subclass of one of these classes, and expose it +to QML either as a type or context property. + +\section3 Read-only Data Model + +The custom model must reimplement the following methods to enable read-only +access to the data from QML: + +\list +\li \l{QAbstractItemModel::}{roleNames}() to expose the role names to the + QML frontend. For example, the following version returns the selected + table's field names as role names: + \code + QHash<int, QByteArray> SqlQueryModel::roleNames() const + { + QHash<int, QByteArray> roles; + // record() returns an empty QSqlRecord + for (int i = 0; i < this->record().count(); i ++) { + roles.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8()); + } + return roles; + } + \endcode +\li \l{QSqlQueryModel::}{data}() to expose SQL data to the QML frontend. + For example, the following implementation returns data for the given + model index: + \code + QVariant SqlQueryModel::data(const QModelIndex &index, int role) const + { + QVariant value; + + if (index.isValid()) { + if (role < Qt::UserRole) { + value = QSqlQueryModel::data(index, role); + } else { + int columnIdx = role - Qt::UserRole - 1; + QModelIndex modelIndex = this->index(index.row(), columnIdx); + value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole); + } + } + return value; + } + \endcode +\endlist + +The QSqlQueryModel class is good enough to implement a custom read-only +model that represents data in an SQL database. The +\l{Qt Quick Controls 2 - Chat Tutorial}{chat tutorial} example +demonstrates this very well by implementing a custom model to fetch the +contact details from an SQLite database. + +\section3 Editable Data Model + +Besides the \c roleNames() and \c data(), the editable models must reimplement +the \l{QSqlTableModel::}{setData} method to save changes to existing SQL data. +The following version of the method checks if the given model index is valid +and the \c role is equal to \l Qt::EditRole, before calling the parent class +version: + +\code +bool SqlEditableModel::setData(const QModelIndex &item, const QVariant &value, int role) +{ + if (item.isValid() && role == Qt::EditRole) { + QSqlTableModel::setData(item, value,role); + emit dataChanged(item, item); + return true; + } + return false; + +} +\endcode + +\note It is important to emit the \l{QAbstractItemModel::}{dataChanged}() +signal after saving the changes. + +Unlike the C++ item views such as QListView or QTableView, the \c setData() +method must be explicitly invoked from QML whenever appropriate. For example, +on the \l[QML]{TextField::}{editingFinished}() or \l[QML]{TextField::}{accepted}() +signal of \l[QtQuickControls]{TextField}. Depending on the +\l{QSqlTableModel::}{EditStrategy} used by the model, the changes are either +queued for submission later or submitted immediately. + +You can also insert new data into the model by calling +\l {QSqlTableModel::insertRecord}(). In the following example snippet, +a QSqlRecord is populated with book details and appended to the +model: + +\code + ... + QSqlRecord newRecord = record(); + newRecord.setValue("author", "John Grisham"); + newRecord.setValue("booktitle", "The Litigators"); + insertRecord(rowCount(), newRecord); + ... +\endcode + \section2 Exposing C++ Data Models to QML The above examples use QQmlContext::setContextProperty() to set |