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
相关产品推荐
相关产品推荐

