Automagically generate labels and editing widgets for a QDataWidgetMapper
I have a QTableView used to show a QSqlTableModel (the "master" in a master/detail view). They both work fine.
Now, I would like to use the same QSqlTableModel with a record-specific editing form (the "detail" in a master/detail view). I'm currently using QDataWidgetMapper to map my editing widgets to the underlying model fields and a form layout to place the widgets on the hosting form (the dialog box).
The problem is that I have a lot of (small) tables and views. As a consequence, I would be happy to generate the form automagically at run-time (on the basis of the information carried by the QTableModel). To do this, I need both the names of the fields (used by the QDataWidgetMapper labels) and their datatypes (used to create the "buddy" editing widgets).
I can easily get the names of the database/model fields using QSqlTableModel->headerData() and use them to create the labels for my QDataWidgetMapper.
Instead, I cannot see a way to get the datatypes associated to these fields (char string, integer, etc.). As a consequence, I cannot create the right editing widgets for them (editLine rather than spinBox, etc.).
Does anybody know how I can get this information from QSqlTableModel (maybe via a QItemDelegate or via a QSqlRecord)? Is this information available at all?
ALTERNATIVE ONE: As long as I can understand, QTableView generates its editing widgets on-demand thanks to QStyledItemDelegate. Of course, I would be happy to use the same technique but... how?
ALTERNATIVE TWO: Would it be simpler/better to avoid QDataWidgetMapper and use instead the "classic" SQL query approach (that is: query the DB, "manually" build your form, CRUD your data and so on)?
I don't have the solution, but I'm doing a project with almost the same requirements. In the meantime I've prepared a struct that I use to store the name of the field, the label (I could need to translate it to another form from the database one) and other stuff that aims to allow me to create the mapping, including the type. So far the type is manually inserted field by field, but having a way to extract it from table metadata could be better.
It should be using the qsqlrecord, get qsqlfield and then get the type as "qvariant type":http://developer.qt.nokia.com/doc/qt-4.8/qvariant.html#Type-enum. Not sure if there is a shortcut to this path. Mya it be there a specific "role":http://developer.qt.nokia.com/doc/qt-4.8/qabstractitemmodel.html#itemData in the item for such information?
This is actually the "alternative two" I mentioned in my post.
I could perform a query against the database with QSqlQuery(), get a QSqlRecord() from the query result and a QSqlField from the record. QSqlField has a type() method that returns the type of the database field. Unfortunately, this info is not reliable:
"QVariant::Type QSqlField::type () const
Returns the field's type as stored in the database. Note that the actual value might have a different type, Numerical values that are too large to store in a long int or double are usually stored as strings to prevent precision loss."
[From: "QSqlField documentation":http://developer.qt.nokia.com/doc/qt-4.8/qsqlfield.html#type]
As long as I can see, there isn't any role that can be used for this task (see: "Qt Roles Documentation":http://developer.qt.nokia.com/doc/qt-4.8/qt.html#ItemDataRole-enum)
If forced, I will (try to) go down this path but I would be much more happy to rely on the existing QSqlTableModel and on the QDataWidgetMapper data-widget mapping.
I just discovered that up to Qt3 it was used to exist a QSqlForm and that it is still supported (but deprecated):
This would have been very near to what I was looking for.
Strangely enough, starting from Qt 4.X this component has been abandoned. The existing SQL Module contains just a Table and a Tree View (both well fit for the "master" view in a typical master/detail architecture). No more Form View (useful for the "detail" part of the master/detail). See:
"Qt SQL Programming":http://developer.qt.nokia.com/doc/qt-4.7/sql-programming.html
"Porting to Qt4":http://developer.qt.nokia.com/doc/qt-4.7/porting4.html
This is quite surprising, given that database front-ends (and database editing/reading forms) are a typical use-case for the Qt Library.
I wonder if this feature is planned for re-introduction in Qt5 or later.