Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using an existing (row, column) C++ model with QtQuick (Grid, TableView)

I have some models that use the QAbstractItemModel rules for retrieving and providing data for a table.

My example model has multiple columns and rows. Unfortunately QtQuick widgets can only handle a single column. Other "columns" are added to the QtQuick widgets by way of roles. So multiple columns in the view match to the same column in the model. Other model columns are ignored, as explained in this question and its answer

I was thinking that it should not be too difficult to provide an abstraction for QML to be used on the C++ side (as a QAbstractProxyModel) which when asked for row N, modulos it by the column count of the source model and retrieves the data from the resulting actual column. This would appear to work for Grid, but won't work for TableView as it relies on TableViewColumn and role names instead of using only continuous row indices. For that, the proxy model would need to distinguish by the role which column of the source model to retrieve from.

The snippet present in the answer to http://qt-project.org/forums/viewthread/41793 does that for adoping QSqlTableModel, but still misses translating a lot of the signals to be usable. Like I imagine if the SQL source model would emit columnsInserted, it should translate to a signal dataChanged with the new roles chosen for that column and a change of the available role names. The QMLifyProxyModel appears to be better, but not production ready and dead for 4 years now, it seems.

How can we best fix this so that the two worlds work together fluently, according to the official recommendation? Why don't QtQuick views use the (row, column) notation that QAbstractItemModel and QTableView has been using already?

like image 579
Johannes Schaub - litb Avatar asked Oct 12 '14 19:10

Johannes Schaub - litb


1 Answers

Part of the difficulty is that the way QtQuick use models is stricter than QWidget views', so it could be worth trying to achieve this the other way around; converting models to use roles and use a proxy model to map roles to column indexes + headerData the same way that TableViewColumn does, but for QWidget views. The column insertion and removal signals should be easier to handle if the source is a static number of roles rather than a changing number of columns.

Sadly this won't help for built-in or more complex models.

Most QtQuick views have been designed for 1D models when phones were its design target. Roles were used to map unordered properties of a single row/item to their scripted name.

TableView came a few years later and seems to be the one that should have done the extra mile to allow using 2D models, but it would probably have been quite some additional work at a time where QtQuick was already quite a beast, especially since TableView was mostly written in QML itself.

like image 75
jturcotte Avatar answered Oct 10 '22 01:10

jturcotte