I have class with QSqlDatabase and with pointer to QSqlTableModel in one class. I use pointer to QSqlTableModel, because initialization of database is going on in constructor and after that I create QSqlTableModel using this database (also in constructor but in heap already).
This class is registered type in qml and so I create it in QML. How is it better to point out TableView to the QSqlTableModel pointer of this class? If it is possible.
Asked
Active
Viewed 1,369 times
1

alr
- 1,332
- 3
- 13
- 23
1 Answers
3
It is not entirely clear what you're asking. I'm going to assume you want to share a pointer to your model with QML.
Have a
Q_PROPERTY
for it. AllQ_PROPERTY
s are automatically visible to QML.When returning
QSqlTableModel*
you need to register that type, too. E.g.qmlRegisterUncreatableType<QSqlTableModel>( "NameOfModuleInQML", 1, 0, "QSqlTableModel", "Cannot instanciate QSqlTableModel from QML");
Note that you cannot do this then:
property QSqlTableModel mytabmodel
do this instead if you need to:
property QtObject mytabmodel
Return it from a method of a class registered with QML (note that you must return
QObject*
). This is very likely what you want. E.g.class SomeClass : public QObject { // ... public: Q_INVOKABLE QObject *model() { return tableModel; } // ... };
Then you can do this in QML:
TableView { model: instanceOfYourclass.model() // other bindings TableViewColumn { title: qsTr("Name") role: "Name" width: 150 } // and so on }
You can create a singleton
QObject *tableModelProvider(QQmlEngine *engine, QJSEngine *scriptEngine) { (void)engine; (void)scriptEngine; return new QSqlTableModel(...); } qmlRegisterSingletonType<QSqlTableModel>("NameOfModule", 1, 0, "NameInQML", tableModelProvider);
This is a suitable approach if there is and ever will be only one instance of your model and if you don't need much to initialize it.
Set your model as a context property
QQmlEngine engine; // .. engine.rootContext()->setContextProperty("nameInQml", yourTableModelInstance);

dom0
- 7,356
- 3
- 28
- 50
-
If I use the first case you wrote (but without creating property QtObject in QML) I get the run-time error: "QMetaProperty::read: Unable to handle unregistered datatype 'QSqlTableModel' for property 'MyClass::tableModel'". If I use this with creating of property as you wrote I get "Unable to assign [undefined] to QObject*" error. The second method with Q_INVOKABLE works without errors but I cannot see data in TableView (I'll try to investigate it more deeply). – alr Oct 12 '14 at 14:14
-
The model is declared in class as a "QSqlTableModel *m_tableModel". I am not sure, is it actually right to return pointer to model to QML instead of object? – alr Oct 12 '14 at 14:36
-
When using option 1) and returning QSql... you *need* to register the type as pointed out above. Data being invisible is likely an issue of role names, check what's the output of `qDebug() << yourmodel->roleNames();` (include `
` for this) is. – dom0 Oct 12 '14 at 17:06 -
You likely need to set up the model before passing it the first time to a QML view, I guess. – dom0 Oct 12 '14 at 17:06
-
Okay, it seems QSqlTableModel does not export role names (sadly). See http://qt-project.org/wiki/How_to_use_a_QSqlQueryModel_in_QML – dom0 Oct 12 '14 at 17:10
-
That is: you need to subclass QSqlTableModel and re-implement roleNames, returning a mapping column <-> role name. Then you use those role names in the TableViewColumn to access the data. – dom0 Oct 12 '14 at 17:12
-
Found example here (http://qt-project.org/forums/viewthread/41793), it works, but cells not editable and not updating when I insert something new. Anyway, the second proposed approach covers the question. – alr Oct 13 '14 at 13:15
-
@dom0 very detailed answer thank you. For (2) I'd like to point out that the returned pointer must explicitly be `QObject*`. If it is `QSqlTableModel*`, the behavior gets weird: Sometimes it is properly recognized by the qml engine and sometimes not (resulting in the pointer being `undefined`). – Ayberk Özgür Jun 27 '16 at 09:16
-
@AyberkÖzgür in C++ , returning an object of base type (`QObject`) is not recommended for derived class objects (`QSqlTableModel`) .. isn't that UB ? while it works for pointer objects only .. it could eventually also be UB .. dont know! – Mohammad Kanan Jun 22 '19 at 18:11