我从我的 ListView QMLSQLite 数据库

问题描述

我正在尝试显示同一数据库中的两个表中的数据。数据库 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,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 应该代表来自两个表的数据:PlanOnePlanTwo

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 交换,例如:

const char* MysqLModelTwo::sql_SELECT = "SELECT * FROM PlanTwo";

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

qmlRegisterType<MysqLModelOne>("com.sweak.MysqLmodelone",1,"MysqLModelOne");
qmlRegisterType<MysqLModelTwo>("com.sweak.MysqLmodeltwo","MysqLModelTwo");
qmlRegisterType<DatabaseHandler>("com.sweak.databasehandler","DatabaseHandler");

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

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

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

解决方法

问题出在程序的 QML 部分。在尝试访问表中的字段时将 ModelOneModelTwo 绑定到每个 model 的属性 ListView 后,无需执行此操作这样:

Text {
    text: modelOne.Time
}

相反,它应该是:

Text {
    text: Time
}