You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QML读取XML文件后显示数据报错:modelData未定义

问题:QML无法显示C++读取的XML数据,报错ReferenceError: modelData is not defined

我在C中读取XML文件并将数据保存到QVariantList中,C调试输出显示数据正常,说明XML读取逻辑没问题。已在main.cpp中建立C++与QML的关联,但QML无法显示XML条目,持续报错ReferenceError: modelData is not defined,目标是显示多行数据。


相关代码文件

qml_xmlitemsclass.h

class QML_XmlItemsClass : public QObject 
{
    Q_OBJECT    
    Q_PROPERTY(QVariantList ItemsTable_qvm READ getItemsTable_qvm WRITE setItemsTable_qvm NOTIFY updateItemsTable_qvm) 
        
    public:     
    Q_INVOKABLE QVariantList getItemsTable_qvm() const         { return ItemsTable; }       
    void        setItemsTable_qvm(const QVariantList &newh)    { if (ItemsTable != newh)  { ItemsTable = newh; emit updateItemsTable_qvm(); } }          
    
    signals:    
    void        updateItemsTable_qvm();          
    
    private:    
    QVariantList ItemsTable;          
}

qml_xmlitemsclass.cpp

bool QML_XmlItemsClass::GetItems() 
{
    QFile FileIn("//path to the xml file//");
    FileIn.open(QIODevice::ReadOnly);

    QXmlStreamReader xmlReader(&FileIn);
    ItemsTable.clear();

    while (!xmlReader.atEnd() && !xmlReader.hasError())
    {
        xmlReader.readNext();

        // 仅处理目标元素
        if (xmlReader.isStartElement() && xmlReader.name().toString() == "Data")
        {
            QVariantMap itemData;

            // XML结构示例: <Data key="value" />
            foreach (const QXmlStreamAttribute &attr, xmlReader.attributes())
            {
                itemData["key"] = attr.name().toString();
                itemData["value"] = attr.value().toString();
            }
            ItemsTable.append(itemData);
        }        
    }

    qDebug() << "TableData:" << ItemsTable; 
    setConfigurationTable_qvm(ConfigurationTable);
    return true; 
}

Main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "qml_xmlitemsclass.h"

QML_XmlItemsClass              QML_XmlItemsObj;

int main(int argc, char *argv[])
{    
    QGuiApplication app(argc, argv);
    qmlRegisterType<QML_ConfigurationClass>("QML_XmlItemsClass", 0, 1, "QML_XmlItemsClass");
    
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("QML_XmlItemsObj", &QML_XmlItemsObj);
    
    QObject::connect(
        &engine,
        &QQmlApplicationEngine::objectCreationFailed,
        &app,
        []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.loadFromModule("PS1724", "Main");    

    int ret = app.exec();
    
    return ret;
}

LoadXmlItems.qml

import QtQuick
import QtQuick.Controls.Basic

Item
{   
    id: theRoot
    height: 800; width: 1280;
    anchors.top: parent.top;
    
    Rectangle
    {
        id: availableItemsDisplayContainer
        anchors { left: parent.left; right: parent.right; margins: 3; }
        color: "#003951";
        height: 430;
        radius: 5;

        ListView
        {
            anchors.fill: parent
            model: QML_XmlItemsObj.ItemsTable_qvm
           
            delegate:
            Rectangle
            {
                required property int index

                width: ListView.view.width
                height: 40 // 设置高度避免条目重叠
                color: index % 2 === 0 ? "#D5A824" : "#E3C15D" // 交替行高提升可读性

                Row
                { // 使用Row横向排列键值对
                    spacing: 10 // 键值文本间留空

                    Text
                    {
                        text: modelData["key"]                        
                        color: "black"
                        font.pointSize: 12                        
                    }

                    Text
                    {
                        text: modelData["value"]
                        color: "black"
                        font.pointSize: 12                        
                    }
                }
            }
        }
    }        
}

解决方案

1. 修复QML中modelData的访问方式

Qt Quick 2.x及以后版本中,使用QVariantList作为ListView的model时,不能直接隐式使用modelData,需要显式声明属性或改用model关键字访问:

修改delegate部分:

delegate:
Rectangle
{
    required property int index
    required property var modelData // 显式声明modelData属性

    width: ListView.view.width
    height: 40
    color: index % 2 === 0 ? "#D5A824" : "#E3C15D"

    Row
    {
        spacing: 10

        Text
        {
            text: modelData.key // 或直接用 model.key
            color: "black"
            font.pointSize: 12                        
        }

        Text
        {
            text: modelData.value // 或直接用 model.value
            color: "black"
            font.pointSize: 12                        
        }
    }
}

2. 修正C++属性更新的笔误

在qml_xmlitemsclass.cpp的GetItems函数末尾,错误调用了setConfigurationTable_qvm,应改为对应属性的设置函数:

setItemsTable_qvm(ItemsTable);

否则QML无法收到数据更新的通知。

3. 修复main.cpp中的类型注册错误

main.cpp中注册的类型是QML_ConfigurationClass,与实际类名QML_XmlItemsClass不符,修正为:

qmlRegisterType<QML_XmlItemsClass>("QML_XmlItemsClass", 0, 1, "QML_XmlItemsClass");

4. 确保触发XML读取操作

在main.cpp中添加GetItems调用,否则ItemsTable_qvm会是空的:

int main(int argc, char *argv[])
{    
    QGuiApplication app(argc, argv);
    qmlRegisterType<QML_XmlItemsClass>("QML_XmlItemsClass", 0, 1, "QML_XmlItemsClass");
    
    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("QML_XmlItemsObj", &QML_XmlItemsObj);

    // 调用XML读取函数
    QML_XmlItemsObj.GetItems();
    
    QObject::connect(
        &engine,
        &QQmlApplicationEngine::objectCreationFailed,
        &app,
        []() { QCoreApplication::exit(-1); },
        Qt::QueuedConnection);
    engine.loadFromModule("PS1724", "Main");    

    int ret = app.exec();
    
    return ret;
}

内容的提问来源于stack exchange,提问作者coder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 14:05:02