I am trying to display data that is in two tables in the same database. The tables in the database plan_db.sqlite
were created using these queries:
CREATE TABLE PlanOne (ID INTEGER NOT NULL PRIMARY KEY, Time VARCHAR(5), Name VARCHAR(50));
CREATE TABLE PlanTwo (ID INTEGER NOT NULL PRIMARY KEY, Time VARCHAR(5), Name VARCHAR(50));
After inserting some data the structure of it looks like this:
PlanOne:
1|10:00|Event 1
2|14:00|Event 2
PlanTwo:
1|12:00|Event 3
2|16:00|Event 4
The connection is estabilished in the class DatabaseHandler
:
QSqlDatabase plan_db = QSqlDatabase::addDatabase("QSQLITE", "plan_connection");
Then I have two QSqlQueryModel
s that are supposed to represent the data from two tables: PlanOne
and PlanTwo
:
MySqlModelOne
:
class MySqlModelOne : public QSqlQueryModel
{
Q_OBJECT
public:
explicit MySqlModelOne(QObject* parent = Q_NULLPTR);
Q_INVOKABLE void refresh();
QHash<int, QByteArray> roleNames() const override;
QVariant data(const QModelIndex &index, int role) const override;
private:
QSqlDatabase plan_db = QSqlDatabase::database("plan_connection");
QSqlQuery plan_qry;
const static char* COLUMN_NAMES[];
const static char* SQL_SELECT;
};
MySqlModelOne::MySqlModelOne(QObject* parent) : QSqlQueryModel(parent)
{
if (plan_db.open()) qDebug("Plan database opened");
else qDebug("Plan database not opened");
plan_qry = QSqlQuery(plan_db);
refresh();
}
void MySqlModelOne::refresh()
{
plan_qry.exec(SQL_SELECT);
this->setQuery(plan_qry);
}
QHash<int, QByteArray> MySqlModelOne::roleNames() const
{
int idx = 0;
QHash<int, QByteArray> roleNames;
while (COLUMN_NAMES[idx]) {
roleNames[Qt::UserRole + idx + 1] = COLUMN_NAMES[idx];
idx++;
}
return roleNames;
}
QVariant MySqlModelOne::data(const QModelIndex &index, int role) const
{
QVariant value = QSqlQueryModel::data(index, role);
if(role < Qt::UserRole)
{
value = QSqlQueryModel::data(index, role);
}
else
{
int columnIdx = role - Qt::UserRole - 1;
QModelIndex modelIndex = this->index(index.row(), columnIdx);
value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
}
return value;
}
const char* MySqlModelOne::COLUMN_NAMES[] = { "ID", "Time", "Name", NULL};
const char* MySqlModelOne::SQL_SELECT = "SELECT * FROM PlanOne";
MySqlModelTwo
is the copy of MySqlModelOne
with appropriate changes like swapping every One
with Two
e.g:
const char* MySqlModelTwo::SQL_SELECT = "SELECT * FROM PlanTwo";
The classes are properly exposed to QML in main.cpp
:
qmlRegisterType<MySqlModelOne>("com.sweak.mysqlmodelone", 1, 0, "MySqlModelOne");
qmlRegisterType<MySqlModelTwo>("com.sweak.mysqlmodeltwo", 1, 0, "MySqlModelTwo");
qmlRegisterType<DatabaseHandler>("com.sweak.databasehandler", 1, 0, "DatabaseHandler");
And finally the QML code that is supposed to display the data from QSqlQueryModel
s using ListView
s:
Window {
width: 640
height: 480
visible: true
DatabaseHandler {
id: dataBaseHandler
}
MySqlModelOne {
id: modelOne
}
MySqlModelTwo {
id: modelTwo
}
ListView {
id: listViewOne
model: modelOne
width: 100
height: width
anchors.left: parent.left
delegate: RowLayout {
Text {
text: modelOne.Time
}
Text {
text: modelOne.Name
}
}
}
ListView {
id: listViewTwo
model: modelTwo
width: 100
height: width
anchors.left: listViewOne.right
delegate: RowLayout {
Text {
text: modelTwo.Time
}
Text {
text: modelTwo.Name
}
}
}
After executing the program, the program window is blank (obviously) and I get the following error messages:
Plan database opened
Plan database opened
qrc:/main.qml:42:17: Unable to assign [undefined] to QString
qrc:/main.qml:45:17: Unable to assign [undefined] to QString
qrc:/main.qml:42:17: Unable to assign [undefined] to QString
qrc:/main.qml:45:17: Unable to assign [undefined] to QString
qrc:/main.qml:66:17: Unable to assign [undefined] to QString
qrc:/main.qml:69:17: Unable to assign [undefined] to QString
qrc:/main.qml:66:17: Unable to assign [undefined] to QString
qrc:/main.qml:69:17: Unable to assign [undefined] to QString
First two lines assure me that the database was properly opened in both QSqlQueryModel
s but 8 lines that come next suggest to me that the data might not have been retrieved from both tables or it was retrieved but the format is undefined
and obviously can't be assigned to QString
and consequently can't be displayed via the ListView
s. Can the problem be in the fact that I try to retrieve the data simultaneously from the same database through two different models? If so, how can I do this without causing such errors? Or maybe You have other ideas how to retrieve data from different tables in the same database using QSqlQueryModel
.
The problem was in the QML part of the program. After binding the ModelOne
and ModelTwo
to the property model
of each of the ListView
s while trying to get access to the fields in tables there was no need to to do this this way:
Text {
text: modelOne.Time
}
instead it should have been:
Text {
text: Time
}