Home > Net >  QSqlTableModel: change database after constructing
QSqlTableModel: change database after constructing

Time:04-11

I'm creating an application which uses QSqlDatabase and QSqlTableModel for inserting and retaining data from an SQLite database file.

The database instance is being created in MyApplication:

MyApplication.h

#include <QSqlDatabase>

// ...

class MyApplication
{
public:
    // ....
private:
    QSqlDatabase _database;
};

MyApplication.cpp

MyApplication::start()
{
    // ...
    _database = QSqlDatabase::database();
    // ...
}

For data model handling I'm using an overloaded class of QSqlTableModel:

SqlContactModel.h

#include <QSqlTableModel>

class SqlContactModel : public QSqlTableModel
{
public:
    // ...

    void setDatabase(const QSqlDatabase& database) { _database = database };

private:
    QSqlDatabase _database;
};

SqlContactModel overloads the typical methods such as data(), roleNames() etc.

My instance of SqlContactModel is used in QML, thus I'm creating the instance in my main.cpp as follows:

main.cpp

int main()
{
    // ...
    qmlRegisterType<SqlContactModel>("io.taibsu.qxmt", 1, 0, "SqlContactModel");
}

Now since it's being created via qmlRegisterType, I can't pass any parameters in the constructor to set a different database in the SqlContactModel.

I need to pass a different database to it since I'm using multiple different overloaded QSqlTableModel classes (e.g., the other class is called SqlConversationModel and shall use the same _database instance which is used in MyApplication).

Now there are two ways to solve this: either pass the database somehow to my SqlTableModel subclasses via QML or find another way to tell the TableModel to not use its own database instance but the one already there.

Now my questions are:

  1. How can I use a single database in different table models?
  2. Is there a way to pass parameters when constructing a class instance in QML?

CodePudding user response:

The best way probably is to set up your database from a controller class in C , give that controller a (read only & constant) properly contactsModel and expose the controller as a singleton to QML. This way you can setup the database from C (where your business logic belongs) while you can access your data from QML. There probably isn’t even a need to have that property be another type than QAbstractItemModel* so you keep the freedom to modify it to another model type if needed in the future without affecting your QML. Such decoupling is desirable.

  • Related