Я получаю неопределенные данные из QSqlQueryModel в моем ListView QML (база данных SQLite)

Я пытаюсь отобразить данные из двух таблиц в одной базе данных. Таблицы в базе данных plan_db.sqlite были созданы с помощью следующих запросов:

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));

После вставки некоторых данных структура выглядит следующим образом:

PlanOne:
1|10:00|Event 1
2|14:00|Event 2
PlanTwo:
1|12:00|Event 3
2|16:00|Event 4

Соединение устанавливается в классе DatabaseHandler:

QSqlDatabase plan_db = QSqlDatabase::addDatabase("QSQLITE", "plan_connection");

Затем у меня есть два QSqlQueryModel, которые должны представлять данные из двух таблиц: PlanOne и 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 является копией MySqlModelOne с соответствующими изменениями, такими как замена каждого One на Two, например:

const char* MySqlModelTwo::SQL_SELECT = "SELECT * FROM PlanTwo";

Классы правильно отображаются в QML в 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");

И, наконец, код QML, который должен отображать данные из QSqlQueryModels, используя ListViews:

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
            }
        }
    }

После выполнения программы окно программы пустое (очевидно), и я получаю следующие сообщения об ошибках:

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

Первые две строки убеждают меня, что база данных была правильно открыта в обе QSqlQueryModels, но следующие 8 строк предполагают, что данные, возможно, не были извлечены из обеих таблиц или были получены, но формат undefined и, очевидно, не может быть назначен на QString и, следовательно, не может отображаться через ListViews. Может проблема в том, что я пытаюсь получить данные одновременно из одной и той же БД через две разные модели? Если да, то как я могу это сделать, не вызывая таких ошибок? Или, может быть, у Вас есть другие идеи, как получить данные из разных таблиц в одной базе данных, используя QSqlQueryModel.


person sweak    schedule 17.02.2021    source источник


Ответы (1)


Проблема была в части QML программы. После привязки ModelOne и ModelTwo к свойству model каждого из ListView при попытке получить доступ к полям в таблицах не было необходимости делать это следующим образом:

Text {
    text: modelOne.Time
}

вместо этого должно было быть:

Text {
    text: Time
}
person sweak    schedule 17.02.2021