我在 ListView QML(SQLite 数据库)中从 QSqlQueryModel 获取未定义的数据
I get undefined data from QSqlQueryModel in my ListView QML (SQLite database)
我正在尝试显示位于同一数据库两个表中的数据。数据库 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
连接建立在 class DatabaseHandler
:
QSqlDatabase plan_db = QSqlDatabase::addDatabase("QSQLITE", "plan_connection");
然后我有两个 QSqlQueryModel
s 应该表示来自两个表的数据: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";
classes 在 main.cpp
中正确暴露给 QML:
qmlRegisterType<MySqlModelOne>("com.sweak.mysqlmodelone", 1, 0, "MySqlModelOne");
qmlRegisterType<MySqlModelTwo>("com.sweak.mysqlmodeltwo", 1, 0, "MySqlModelTwo");
qmlRegisterType<DatabaseHandler>("com.sweak.databasehandler", 1, 0, "DatabaseHandler");
最后是应该使用 ListView
s 显示来自 QSqlQueryModel
s 的数据的 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
}
}
}
执行程序后,程序 window 是空白的(很明显),我收到以下错误消息:
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 部分。在尝试访问表中的字段时,将 ModelOne
和 ModelTwo
绑定到每个 ListView
的 属性 model
之后,没有必要要这样做:
Text {
text: modelOne.Time
}
应该是:
Text {
text: Time
}
我正在尝试显示位于同一数据库两个表中的数据。数据库 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
连接建立在 class DatabaseHandler
:
QSqlDatabase plan_db = QSqlDatabase::addDatabase("QSQLITE", "plan_connection");
然后我有两个 QSqlQueryModel
s 应该表示来自两个表的数据: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";
classes 在 main.cpp
中正确暴露给 QML:
qmlRegisterType<MySqlModelOne>("com.sweak.mysqlmodelone", 1, 0, "MySqlModelOne");
qmlRegisterType<MySqlModelTwo>("com.sweak.mysqlmodeltwo", 1, 0, "MySqlModelTwo");
qmlRegisterType<DatabaseHandler>("com.sweak.databasehandler", 1, 0, "DatabaseHandler");
最后是应该使用 ListView
s 显示来自 QSqlQueryModel
s 的数据的 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
}
}
}
执行程序后,程序 window 是空白的(很明显),我收到以下错误消息:
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 部分。在尝试访问表中的字段时,将 ModelOne
和 ModelTwo
绑定到每个 ListView
的 属性 model
之后,没有必要要这样做:
Text {
text: modelOne.Time
}
应该是:
Text {
text: Time
}