无法在 QML ListView 中显示来自 QSqlQueryModel 的数据

问题描述 投票:0回答:1

描述:

我遇到一个问题,无法在 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 中显示数据的任何见解或建议,我将不胜感激。 谢谢!

c++ qml qt6 qsqlquerymodel
1个回答
0
投票

终于

此链接帮助我解决了这个问题: 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;
}
© www.soinside.com 2019 - 2024. All rights reserved.