QML中子模型调用与C++类注册方法咨询
QML乐器管理项目:子模型调用与类注册方案
一、main.cpp中注册相关类
要让QML能够访问C++定义的类,需在main.cpp中完成类型注册,示例代码如下:
#include <QGuiApplication> #include <QQmlApplicationEngine> #include "Item.h" #include "Setlist.h" #include "ModelItem.h" #include "Setlists.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); // 注册自定义类到QML模块,替换为你自己的模块标识 qmlRegisterType<Item>("com.instruments.manager", 1, 0, "Item"); qmlRegisterType<Setlist>("com.instruments.manager", 1, 0, "Setlist"); qmlRegisterType<ModelItem>("com.instruments.manager", 1, 0, "ModelItem"); qmlRegisterType<Setlists>("com.instruments.manager", 1, 0, "Setlists"); QQmlApplicationEngine engine; const QUrl url(u"qrc:/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.load(url); return app.exec(); }
注:com.instruments.manager为自定义模块名,可根据项目需求修改;版本号1.0可按需调整。
二、QML中调用子模型
1. 导入注册模块
在QML文件开头导入已注册的模块:
import com.instruments.manager 1.0
2. 两种调用方式
方式1:QML内直接创建测试数据
Window { width: 640 height: 480 visible: true title: "乐器管理系统" // 创建顶层Setlists模型 Setlists { id: rootSetlists Component.onCompleted: { // 构建第一个Setlist及下属Item let liveSet = Setlist { name: "演出设备组" gear: [ Item { name: "Fender电吉他"; category: "弦乐器"; subcategory: "电声" }, Item { name: "Strymon效果器"; category: "音频配件"; subcategory: "效果处理" } ] } let liveItem = ModelItem { setlist: liveSet } // 构建第二个Setlist及下属Item let practiceSet = Setlist { name: "练习设备组" gear: [ Item { name: "Martin木吉他"; category: "弦乐器"; subcategory: "原声" }, Item { name: "Boss节拍器"; category: "辅助配件"; subcategory: "节奏工具" } ] } let practiceItem = ModelItem { setlist: practiceSet } // 将子模型加入顶层模型 rootSetlists.setlists = [liveItem, practiceItem] } } // 外层ListView展示所有Setlist ListView { anchors.fill: parent model: rootSetlists delegate: Column { width: parent.width padding: 10 spacing: 8 Text { text: model.setlist.name font.bold: true font.pixelSize: 18 } // 内层ListView展示当前Setlist下的乐器Item ListView { width: parent.width height: 140 model: model.setlist delegate: Text { text: `${name} | ${category} > ${subcategory}` font.pixelSize: 14 padding: 4 } } } } }
方式2:从C++传递模型到QML
若在C++中已初始化好Setlists实例,可将其设为QML上下文属性:
在main.cpp中添加:
Setlists *deviceSetlists = new Setlists(&app); // 此处可完成deviceSetlists的数据初始化逻辑 engine.rootContext()->setContextProperty("deviceSetlists", deviceSetlists);
然后在QML中直接使用:
ListView { anchors.fill: parent model: deviceSetlists delegate: Column { width: parent.width padding: 10 spacing: 8 Text { text: model.setlist.name font.bold: true font.pixelSize: 18 } ListView { width: parent.width height: 140 model: model.setlist delegate: Text { text: `${name} | ${category} > ${subcategory}` font.pixelSize: 14 padding: 4 } } } }
关键注意事项
- 需确保
Setlist和Setlists的roleNames()方法正确实现,否则QML无法通过角色名访问数据:Setlist的roleNames示例:QHash<int, QByteArray> Setlist::roleNames() const { QHash<int, QByteArray> roles; roles[ItemNameRole] = "name"; roles[ItemCategoryRole] = "category"; roles[ItemSubcategoryRole] = "subcategory"; return roles; }Setlists的roleNames示例:QHash<int, QByteArray> Setlists::roleNames() const { QHash<int, QByteArray> roles; roles[ItemsRole] = "setlist"; return roles; }
内容的提问来源于stack exchange,提问作者Cacafave
相关产品推荐
相关产品推荐

