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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 17:14:58