Getting data of TableModel passed as Q_PROPERTY in QML
-
I'm using two different
QSqlTableModel
instances to set and retreive data from an SQLite database.
They're being created when constructing anSqlDatabaseController
class:SqlDatabaseController.cpp
SqlDatabaseController::SqlDatabaseController(QObject *parent) : QObject(parent) { // create database driver _database = QSqlDatabase::database(); _contactModel = new SqlContactModel(this, _database); _conversationModel = new SqlConversationModel(this, _database); }
I want to retrieve them in QML to pass them to ListView components using Q_PROPERTY:
SqlDatabaseController.h
class SqlDatabaseController : public QObject { Q_OBJECT Q_PROPERTY(SqlContactModel* contactModel READ contactModel WRITE setContactModel NOTIFY contactModelChanged) Q_PROPERTY(SqlConversationModel* conversationModel READ conversationModel WRITE setConversationModel NOTIFY conversationModelChanged) // ... };
My data is being inserted in my TableModel:
SqlContactModel.cpp
void SqlContactModel::addContact(const QString& contactName, const QString& jid, const QByteArray& avatar) { QSqlRecord newRecord = record(); newRecord.setValue("jid", jid); newRecord.setValue("name", contactName); // ... insertRecord(rowCount(), newRecord); submitAll(); }
The database controller is being registered in my main function:
main.cpp
// ... qmlRegisterType<SqlDatabaseController>("io.taibsu.qxmt", 1, 0, "SqlDatabaseController"); // ...
When creating my QML view, I'm creating an instance of my SqlDatabaseController:
main.qml
SqlDatabaseController { id: sqlDatabaseController objectName: "sqlDatabaseController" onContactModelChanged: { console.log("Contact model changed!"); } }
It's being passed to a different QML component like this:
ContactPage { id: contacts width: parent.width * .25 sqlDatabaseController: sqlDatabaseController // ... }
My ContactsPage component looks as follows:
ContactPage.qml
Page { id: root property var sqlDatabaseController // ... ListView { id: contactsView anchors.fill: parent // ... model: sqlDatabaseController.contactModel delegate: ItemDelegate { property string delegateUserName: model.jid // <-- error comes up here // ... } } }
Now, when trying to start my application and get the model information, I keep getting an error:
qrc:/ContactPage.qml:47:13: Unable to assign [undefined] to QString
I previously had my TableModel registered in my main function directly as
SqlContactModel
type, where it worked:ContactPage.qml
ListView { // ... model: SqlContactModel {} delegate: ItemDelegate { property string delegateUserName: model.jid // <-- worked before! // ... } // ... }
But now since I had to refactor a lot and switch to a single SqlDatabaseController class it's hard for me to understand why I can't retrieve my model information when using
Q_PROPERTY(contactModel /* ... */)
.How can I get access to data from a model passed via Q_PROPERTY(SqlContactModel ...) in QML?*
Expected result:
ListView { model: sqlDatabaseController.contactModel delegate: ItemDelegate { property string delegateUserName: model.jid // <-- this way }
returns the data from the
jid
column of my model. -
I dug a bit more into it and debugged my model from QML. there, I found out that the data fields actually do exist, however they're not filled:
qml: objectName: qml: index: 0 qml: row: 0 qml: column: 0 qml: model: QQmlDMAbstractItemModelData(0x155d06dce00) qml: hasModelChildren: false qml: name: undefined qml: jid: undefined qml: avatar: undefined
Which means I probably either don't refresh my model properly after inserting data or my data retrieval methods are not correct:
QVariant SqlContactModel::data(const QModelIndex &index, int role) const { if (role < Qt::UserRole) { return QSqlTableModel::data(index, role); } const QSqlRecord sqlRecord { record(index.row()) }; return sqlRecord.value(role - Qt::UserRole); } QHash<int, QByteArray> SqlContactModel::roleNames() const { QHash<int, QByteArray> names; names[Qt::UserRole] = "name"; names[Qt::UserRole + 1] = "jid"; names[Qt::UserRole + 2] = "avatar"; return names; } void SqlContactModel::addContact(const QString& contactName, const QString& jid, const QByteArray& avatar) { QSqlRecord newRecord = record(); newRecord.setValue("jid", jid); newRecord.setValue("name", contactName); if (!avatar.isEmpty()) { newRecord.setValue("avatar", avatar); } if (!insertRecord(rowCount(), newRecord)) { qWarning() << "[SQL] SqlContactModel: Failed to add contact:" << lastError().text(); return; } if (!submitAll()) { qWarning("[SQL] SqlContactModel: Failed to submit addContact query: %s", qPrintable(lastError().text())); return; } qDebug() << "[SQL] SqlContactModel: Added contact " << contactName << "(" << jid << ") to table " << _tableName << "."; }
Could someone please help me here?
When setting a breakpoint in my data() function, the debugger won't even halt there.