我从我的 ListView QML(SQLite 数据库)中的 QSqlQueryModel 获得未定义的数据 [英] I get undefined data from QSqlQueryModel in my ListView QML (SQLite database)

查看:36
本文介绍了我从我的 ListView QML(SQLite 数据库)中的 QSqlQueryModel 获得未定义的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试显示同一数据库中的两个表中的数据.数据库 plan_db.sqlite 中的表是使用以下查询创建的:

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

DatabaseHandler类中建立连接:

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

然后我有两个 QSqlQueryModel 应该表示来自两个表的数据:PlanOnePlanTwo:

Then I have two QSqlQueryModels 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";

MySqlModelTwoMySqlModelOne 的副本,并进行了适当的更改,例如将每个 OneTwo 交换,例如:

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

这些类在 main.cpp 中正确暴露给 QML:

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

最后是应该使用 ListViews 显示来自 QSqlQueryModels 的数据的 QML 代码:

And finally the QML code that is supposed to display the data from QSqlQueryModels using 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
            }
        }
    }

执行程序后,程序窗口是空白的(显然)并且我收到以下错误消息:

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

前两行向我保证在两个 QSqlQueryModel 中都正确打开了数据库,但接下来的 8 行向我表明数据可能未从两个表中检索到,或者已检索但格式是 undefined 并且显然不能分配给 QString,因此不能通过 ListView s 显示.问题是否在于我尝试通过两个不同的模型同时从同一个数据库中检索数据?如果是这样,我怎样才能做到这一点而不会导致此类错误?或者也许您有其他想法如何使用 QSqlQueryModel 从同一数据库中的不同表中检索数据.

First two lines assure me that the database was properly opened in both QSqlQueryModels 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 ListViews. 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.

推荐答案

问题出在程序的 QML 部分.将 ModelOneModelTwo 绑定到每个 ListView 的属性 model 后,同时尝试访问表中的字段不需要这样做:

The problem was in the QML part of the program. After binding the ModelOne and ModelTwo to the property model of each of the ListViews while trying to get access to the fields in tables there was no need to to do this this way:

Text {
    text: modelOne.Time
}

相反,它应该是:

Text {
    text: Time
}

这篇关于我从我的 ListView QML(SQLite 数据库)中的 QSqlQueryModel 获得未定义的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆