I want to produce a simple enough application which uses a QTreeView widget to show hierarchical data from a SQLite3 (flat) table, use QDataWidgetMapper to populate some lineedit fields, allow user to edit, which in turn updates the table. Simple & basic (for most!).
I have been working on the basis that the following process would be the best way of doing this:
- Connect to Dbase
- Query data
- Create and populate custom QAbstractItemModel from the data (manipulating it through a
dictto create nodes, parents and children dynamically – for each dict entry a ‘node’ is generated with an associated parent) - Use QDatawidgetmapper to populate other widgets
- User edits data
- QAbstractItemModel (QAIM) is updated
- Then have to run an UPDATE, INSERT or whatever query using new values in the QAIM model.
- Refresh the QAIM and associated widgets.
I realise if I were just using a QTableView or QListView I would not need the custom model and could just write straight back into the database. The process I have outlined above seems to mean having to keep two sets of data going – i.e. the SQLite table and the custom QAIM and ensure that they are both kept up to date. This seems a bit cumbersome to me and I’m sure there must be a better way of doing it where the QTreeView is taking its data straight from the SQLite table – with the obvious need for some manipulation to convert the flat data into hierarchical data.
I am wondering, of course, whether I have completely misunderstood the relationship between QAbstractItemModel and the QSQL*Models and I am overcomplicating it through ignorance?
Thanks
What you want is a proxy model that acts as a bridge between
QSql*Modeland the view. For that, you need to subclassQAbstractProxyModel. You have to have a consistent way of finding parent-child relationships in proxy model and mapping them to the source model, so that might require keeping some tally in the proxy model.When you are sub-classing
QAbstractProxyModel, you need to re-define, at minimum, these methods:Also, keep in mind that
QAbstractProxyModeldoes not auto-propagate signals through. So, in order to have the view be aware of changes in source model (like insert, delete, update), you need to pass them in the proxy model (while of course, updating your mappings in the proxy model).It will require some work, but in the end you’ll have a more flexible structure. And it will eliminate all the stuff that you need to do for synchronizing database and custom
QAbstractItemModel.Edit
A custom proxy model that groups items from a flat model according to a given column: