How to Use a QSqlQueryModel in QML

From Qt Wiki
Revision as of 15:49, 14 January 2015 by Maintenance script (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

English Spanish Italian

How to use a QSqlQueryModel in QML

Initial fully detailed approach

Introduction

The software I develop, Photo Parata, is a client server application that uses a sql backend. Most of the time the data Photo Parata displays requires some joins. Because of this, most of the time the models are derived from QSqlQueryModel, not QSqlTableModel.
For QSqlRelationalTableModel, you can find an working but unexplained example at http://wiki.qt.io/QML_and_QSqlTableModel

In this how to, I will walk you through the steps of setting up a custom model for QML, derived from QSqlQueryModel.

I would like to thank Christophe Dumez [cdumez.blogspot.com] for his blog How to use C++ list model in QML [cdumez.blogspot.com]. It was this blog that allowed me to piece the following together.

Other useful sources were : Using_QStandardItemModel_in_QML [developer.nokia.com] and QSqlTableModel in QML [qt.io]

The data source for this example was lifted from one of the Sql examples that ships with Qt, examples\sql\masterdetail [doc.qt.nokia.com]

Step 1: Create a C++ class that derives from QSqlQueryModel:

All the magic happens in the constructor and in the overloaded data() method.

Step 2: Implement two static constants

I always have two constant static variables in each of my models that derive from QSqlQueryModel, COLUMN_NAMES and SQL_SELECT. The order of the column names in COLUMN_NAMES must match the order they are listed in the SELECT statement

Step 3: Set the roleNames in the constructor

This is where all the magic really happens. The QML will reference the different columns by the role names set on the model.

Step 4: implement the data() method and the refresh() method:

As long as the role that is requested is not a user role, return the default. But if the role is a user role, return the correct column:

The refresh() method is the most important, without it, the model won’t show anything at all. The best is to stick to the setQuery method from QSqlQueryModel.

Step 5: Allow QML to see the model:

Create an instance of the model (make note that the constructor of the model did query the DB the first time). Then set it as a property on the viewer’s context, in this case I called it artistModel:

Step 6: Create the QML list

Since the model was exposed in step 5, the model exists and is ready to be used in QML. Simply set the model of the ListView to the name give in step 5.

Step 7: Create the QML delegate used by the list

And finally implementation of the delegate. Notice here how the names set in the roleModel are used as the values to bind to the text property of the Text objects:

ArtistItemDelegate.qml

Source code is no longer available on my website, so feel free to contact me for the complete source code, I will be happy to share!

A more generic approach

Based on the initial wiki article I came up with a more generic approach that allow to use the same class for all your models instead of creating a derived class for each model.

Here it is :

sqlquerymodel.h

sqlquerymodel.cpp

And use it like this :

Categories: