我遇到一个问题,无法在 QML ListView 中显示从 QSqlQueryModel 检索的数据。尽管在 C++ 后端成功加载数据并确认其存在,但 QML ListView 显示每个项目的未定义值。
以下是我的设置的相关详细信息:
环境:我正在使用Qt进行应用程序开发,版本为[插入版本号]。该应用程序是使用 C++ 开发后端逻辑,使用 QML 开发前端 UI。
问题描述:当尝试在 QML ListView 中显示从 QSqlQueryModel 检索到的数据时,ListView 显示每个项目的未定义值。不过,我已经确认数据已成功加载到C++后端的QSqlQueryModel中。
故障排除步骤:我已经通过在C++后端记录数据来验证数据是否正确加载到QSqlQueryModel中。此外,我还检查了 QSqlQueryModel 的 roleNames() 函数中定义的角色名称,并确保它们与 QML 中使用的属性名称匹配。
预期行为:我希望 QML ListView 显示从 QSqlQueryModel 检索的数据,每个项目显示主机、标签、标签、grpc_port、grpc_username 和 grpc_password 的相应值。
qrc:/qt/qml/content/AgentPanel.qml:104:21: Unable to assign [undefined] to QString
但是在 调试控制台 我可以看到我的模型已正确加载到 C++ 类中:
Query Executed Successfully: true
Number of Rows Retrieved: 27
Row Data: "localhost" "Agent 1" "tag1" 50051 "user1" "pass1"
这是我的
main.cpp
:
int main(int argc, char *argv[])
{
set_qt_environment();
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<InitDb>("com.example", 1, 0, "InitDb");
InitDb db;
// db.initDb();
AgentModel agentModel;
agentModel.loadAgents();
engine.rootContext()->setContextProperty("agentModel", &agentModel);
const QUrl url(u"qrc:/qt/qml/Main/main.qml"_qs);
QObject::connect(
&engine, &QQmlApplicationEngine::objectCreated, &app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.addImportPath(QCoreApplication::applicationDirPath() + "/qml");
engine.addImportPath(":/");
engine.load(url);
if (engine.rootObjects().isEmpty()) {
return -1;
}
return app.exec();
}
我的
agentModel.cpp
#include "agentModel.h"
AgentModel::AgentModel(QObject* parent) : QSqlQueryModel(parent) {}
void AgentModel::loadAgents()
{
QSqlQuery query;
query.prepare("SELECT host, label, tag, grpc_port, grpc_username, grpc_password FROM agents");
if (!query.exec()) {
qDebug() << "Error executing query:" << query.lastError().text();
return;
}
// Clear any existing data in the model
clear();
// Populate the model with the fetched data
setQuery(query);
if (lastError().isValid()) {
qDebug() << "Error loading agents:" << lastError().text();
}
else {
qDebug() << "First Row Data:" << record(0); // Check the label field of the first row
qDebug() << "Query Executed Successfully:" << query.isActive();
qDebug() << "Number of Rows Retrieved:" << rowCount();
}
// Output the data of each row
for (int i = 0; i < rowCount(); ++i) {
qDebug() << "Row Data:" << record(i).value("host").toString()
<< record(i).value("label").toString()
<< record(i).value("tag").toString()
<< record(i).value("grpc_port").toInt()
<< record(i).value("grpc_username").toString()
<< record(i).value("grpc_password").toString();
}
qDebug() << "Agents Loaded Successfully";
}
QHash<int, QByteArray> AgentModel::roleNames() const
{
static const char* COLUMN_NAMES[] = {
"host",
"label",
"tag",
"grpc_port",
"grpc_username",
"grpc_password",
nullptr // Null-terminated array
};
QHash<int, QByteArray> roleNames;
for (int i = 0; COLUMN_NAMES[i] != nullptr; ++i) {
roleNames[Qt::UserRole + i + 1] = COLUMN_NAMES[i];
}
qDebug() << "RoleNames: " << roleNames;
return roleNames;
}
这是我的
AgentPanel.qml
ListView {
id: listView
anchors.top: toolBar.bottom
width: parent.width
height: 300
model: agentModel // Use the model retrieved from c++
Component.onCompleted: {console.log(agentModel.roleNames())}
delegate: Item {
width: listView.width
height: 50
Rectangle {
width: parent.width
height: 50
color: "lightblue"
Text {
anchors.centerIn: parent
text: host // !== undefined ? label : "Unknown Label"
color: "white"
Component.onCompleted: {
// console.log("Row Data:", host, label, tag, grpc_port, grpc_username, grpc_password);
}
}
}
}
}
尽管尝试了各种解决方案,包括不使用角色名称直接访问模型属性,问题仍然存在。
如果您能提供有关如何解决此问题并成功在 QML ListView 中显示数据的任何见解或建议,我将不胜感激。 谢谢!
此链接帮助我解决了这个问题: https://wiki.qt.io/How_to_Use_a_QSqlQueryModel_in_QML
我猜问题是数据 QVariant 未定义:
QVariant AgentModel::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;
}