PDA

View Full Version : Understanding QAbstractTableModel::data() with QSqlQuery



ce_nort
6th April 2016, 19:30
Hello,
I'm fairly new to Qt and C++, and I'm having trouble understanding how exactly to populate a subclass of QAbstractTableModel with data from a QSqlQuery. Say for example I have a sql query that returns the itemID, description, and price for some number of items (data is from two joined tables, so QSqlTableModel will not work). Assume that I want to put the returned data in a QList<QSqlRecord> (as suggested in this post: http://www.qtcentre.org/threads/21144-Subclassing-QAbstractTableModel-Data-from-QSqlQuery ) and also assume I have a subclass of QAbstractTableModel called MyTableModel. Could someone please give me a brief example of what the MyTableModel::data function might look like and how it would be implemented? Should I pass the QList to the constructor for MyTableModel, the data function itself, or none of the above? Any tips would be much appreciated.

anda_skoa
6th April 2016, 19:48
You would probably have that QList as a member of the model.
If you pass it in at the constructor or if you make the model itself to the query is your choice, the second is closer to what the Qt SQL models would do.

In data you get the QModelIndex identifying the cell the view wants data for, so in your case the row() would be the index into the list and the column() which part of the record you have in that respective view column.
The role argument tells you which type of data the view is interested in, in the simplest case you just react to Qt::DisplayRole and return the cell's data, otherwise you just return an default constructed QVariant.

Cheers,
_

ChrisW67
6th April 2016, 19:51
Before you spend a lot of time on this, is there a reason that QSqlQueryModel is not a good solution or starting point?

ce_nort
6th April 2016, 19:57
Is data() automatically called at some point, or do I need to call it myself?

I need to manipulate some of the data before I display it, as well as have an additional column containing data that is not returned by the sql query. Correct me if I am wrong, but my understanding was that neither of these things is possible with QSqlQueryModel?

ChrisW67
6th April 2016, 20:21
You implement data(). Data() will be called by any view, proxy model, or consumer of the data in the model when it requires the content of the model.

If you subclass QSqlQuery model you get most of the data handling for free. To add a derived column to the actual database columns, for example, you could:

Override columnCount() to return QSqlQueryModel::columnCount() plus one.
Override data() to return a derived values for the extra column, and QSqlQueryModel::data() for other columns.
Override headerData() in a similar way to return a decent heading.

If you wanted particular values to render in red by default then your data() could return a different value when the Qt::ForegroundRole is requested for an index, and the base model value for all other roles. The permutations are numerous.

You can also do this sort of manipulation with a proxy model.

ce_nort
6th April 2016, 20:31
Okay, that's some great information to run with, thank you!