响应式网站建设市场,湖北网络推广有限公司,网站背景 手机显示不全,企业酒店的网站建设QML 中关联 C Model 类的两种核心方式#xff1a;import 和 setContextProperty。
这两种方式的本质区别在于 Model 的提供者和作用域。
方式一#xff1a;注册为 QML 类型并 Import 使用
这种方式是将 C 类注册到 QML 类型系统中#xff0c;使其在 QML 中像一个内置类型一样…QML 中关联 C Model 类的两种核心方式import 和 setContextProperty。这两种方式的本质区别在于 Model 的提供者和作用域。方式一注册为 QML 类型并 Import 使用这种方式是将 C 类注册到 QML 类型系统中使其在 QML 中像一个内置类型一样被使用。实现步骤在 C 中注册类型使用 qmlRegisterType 函数将你的 Model 类注册为一个可在 QML 中实例化的类型。在 QML 中 Import在使用该 Model 的 QML 文件中通过 import 语句导入其所在的模块。在 QML 中声明实例化像使用 Rectangle、Text 等元素一样直接使用注册的类名来创建对象。代码示例C 部分 (main.cpp 或某个初始化文件)#include QGuiApplication #include QQmlApplicationEngine #include QQmlContext // 假设你的 Model 类头文件 #include mystringlistmodel.h int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; // 关键步骤将 MyStringListModel 注册为 QML 类型 // 参数模块名(如MyApp)、主版本号、次版本号、QML中的类型名 qmlRegisterTypeMyStringListModel(MyModels, 1, 0, MyStringListModel); engine.load(QUrl(QStringLiteral(qrc:/main.qml))); return app.exec(); }C Model 类 (mystringlistmodel.h/cpp)这里以一个简单的字符串列表模型为例。// mystringlistmodel.h #ifndef MYSTRINGLISTMODEL_H #define MYSTRINGLISTMODEL_H #include QAbstractListModel #include QStringList class MyStringListModel : public QAbstractListModel { Q_OBJECT public: explicit MyStringListModel(QObject *parent nullptr); // 必须重写的函数 int rowCount(const QModelIndex parent QModelIndex()) const override; QVariant data(const QModelIndex index, int role Qt::DisplayRole) const override; // 可选如果需要可编辑重写此函数 bool setData(const QModelIndex index, const QVariant value, int role Qt::EditRole) override; Qt::ItemFlags flags(const QModelIndex index) const override; // 自定义角色 enum Roles { NameRole Qt::UserRole 1, ColorRole }; Q_ENUM(Roles) // 将枚举暴露给 QML // 添加数据的方法 public slots: void addItem(const QString name, const QString color); private: QStringList m_names; QStringList m_colors; }; #endif // MYSTRINGLISTMODEL_H(.cpp 文件实现略重点是展示如何在 QML 中使用)QML 部分 (main.qml)import QtQuick 2.15 import QtQuick.Controls 2.15 import MyModels 1.0 // 导入我们注册的模块 ApplicationWindow { width: 400 height: 300 visible: true // 直接在 QML 中声明并实例化我们的 Model // 就像使用一个普通的 QML Item 一样 MyStringListModel { id: stringModel // 可以在这里直接调用其槽函数来初始化数据 Component.onCompleted: { addItem(Apple, red) addItem(Banana, yellow) addItem(Grape, purple) } } ListView { anchors.fill: parent model: stringModel // 将 ListView 的 model 设置为这个实例 delegate: Rectangle { width: ListView.view.width height: 40 color: model.color // 使用我们在 C 中定义的 ColorRole Text { text: model.name // 使用 NameRole anchors.centerIn: parent } } } }特点与适用场景• 特点◦ 模块化Model 成为 QML 环境的一部分可以被任何导入相应模块的 QML 文件使用。 ◦ 封装性好Model 的创建和配置逻辑可以完全放在 QML 端。 ◦ 可复用性高同一个 Model 类可以在多个地方被实例化。 ◦ 类型安全在编译时就能检查类型错误如果工具支持。• 适用场景◦ 通用的、可复用的 Model 组件。 ◦ 希望将 Model 的创建和生命周期管理完全交给 QML 的场景。 ◦ 构建大型的、模块化的 QML 应用程序。方式二使用 setContextProperty这种方式是在 C 端将一个已经创建好的 QObject 派生类包括 Model实例设置为 QML 引擎的上下文属性使其在整个 QML 上下文中可用。实现步骤在 C 中创建实例在 C 代码中通常是 main 函数中创建你的 Model 类的实例。设置上下文属性使用 QQmlEngine::rootContext()-setContextProperty() 将这个实例注册为一个全局可用的 QML 对象。在 QML 中直接使用在 QML 中可以直接使用你设置的名称来访问这个对象无需 import。代码示例C 部分 (main.cpp) #include QGuiApplication #include QQmlApplicationEngine #include QQmlContext #include mystringlistmodel.h // 同样的 Model 类 int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; // 1. 在 C 端创建 Model 实例 MyStringListModel stringModel; // 可以添加一些初始数据 // stringModel.addItem(...); // 2. 关键步骤将实例设置为上下文属性 // 参数在QML中使用的名称, C对象的指针 engine.rootContext()-setContextProperty(myCppModel, stringModel); engine.load(QUrl(QStringLiteral(qrc:/main.qml))); return app.exec(); }QML 部分 (main.qml)import QtQuick 2.15 import QtQuick.Controls 2.15 // 注意这里没有 ‘import MyModels 1.0’ ApplicationWindow { width: 400 height: 300 visible: true // 注意没有在 QML 中声明 MyStringListModel // 它已经在 C 中被创建好了 ListView { anchors.fill: parent // 3. 直接使用在 C 中设置的上下文属性名 ‘myCppModel’ model: myCppModel delegate: Rectangle { width: ListView.view.width height: 40 color: model.color Text { text: model.name anchors.centerIn: parent } } } // 甚至可以在 Button 的 onClicked 中直接调用 C Model 的方法 Button { text: Add Item anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter onClicked: { // 直接调用 C 对象的槽函数 myCppModel.addItem(New Fruit, green) } } }特点与适用场景• 特点◦ 简单直接对于单个实例或单例模式的 Model 非常方便。 ◦ 控制权在 CModel 的生命周期由 C 控制通常在整个应用运行期间都存在。 ◦ 全局可用一旦设置在所有导入了该上下文的 QML 文件中都可以访问。 ◦ 无需注册类型不需要使用 qmlRegisterType代码稍简洁一些。• 适用场景◦ 应用程序的全局状态管理如用户数据、配置信息。 ◦ 单例服务或管理器类。 ◦ 需要与 C 深度交互、且只有一个实例的 Model。 ◦ 快速原型开发或小型项目。对比总结特性 注册类型 (qmlRegisterType) 设置上下文属性 (setContextProperty)提供者 QML 引擎的类型系统 QML 引擎的根上下文使用方式 import 声明式实例化 直接使用属性名生命周期 QML 垃圾回收机制管理 C 端管理通常是长期存在作用域 模块内可见 整个 QML 上下文可见全局复用性 高可创建多个实例 低通常只有一个实例灵活性 高可在 QML 中任意创建和配置 较低实例化和配置主要在 C典型用例 可复用的 UI 组件、通用 Model 全局状态、单例服务、管理器如何选择• 如果你的 Model 是数据驱动的、需要被多个视图复用、或者其行为和创建逻辑更适合在 QML 中描述请选择 注册类型。• 如果你的 Model 代表一个全局的、单一的应用程序状态或服务并且其生命周期应该由 C 牢牢掌控请选择 设置上下文属性。在实际项目中这两种方式常常结合使用。例如使用上下文属性提供一个全局的配置 Model同时使用注册类型为不同的列表页面提供特定的数据 Model。