QML与C++交互的两种注册方法比较(rootContext 和 qmlRegisterType)

在main.cpp实例化对象调用的过程中,注册是常见的操作之一,目前接触到的方法有两种,两者的目的和使用方式是不同的,通过代码可以直观的
看出来

int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    //注册方法1
    engine.rootContext()->setContextProperty("MyListModel", MyListModel::getInstance());
	//注册方法2
	qmlRegisterType<MyListModel>("ListMod", 1, 0, "MyListModel");

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    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();
}

qmlRegisterType

qmlRegisterType 是一个函数,用于在 QML 引擎中注册 C++ 类型,使得 QML 文件中可以直接使用这些类型。这个函数通常在 C++ 代码中调用,用于将自定义的 C++ 类(特别是那些继承自 QObject 的类)暴露给 QML。

  • 优点:
    • QML 文件中可以直接使用注册的类型,创建其实例,并与其进行交互。
    • 支持类型安全,QML 编辑器(如 Qt Creator)可以提供自动补全和类型检查。
    • 适用于需要多个实例的情况,因为 QML 可以直接创建和管理这些实例。
  • 缺点:
    • 需要 C++ 类与 QML 之间进行明确的类型匹配。
    • 如果类具有复杂的构造函数或需要特定的初始化逻辑,可能需要额外的设置。

在给出的例子中:

qmlRegisterType<MyListModel>("ListMod", 1, 0, "MyListModel");

这里注册了一个名为 MyListModel 的 C++ 类,它在 QML 中的导入模块为 “ListMod”,版本为 1.0,并且可以直接在 QML 中通过 MyListModel 类型名来创建和使用实例。

setContextProperty

setContextProperty 是一个方法,用于将 C++ 对象或值设置为 QML 上下文的属性,这样 QML 文件中就可以通过属性名直接访问它。这通常用于将单例或全局对象暴露给 QML。

  • 优点:
    • 简单直接,适用于将单例或全局对象暴露给 QML。
    • 不需要复杂的类型匹配或注册。
  • 缺点:
    • 不支持类型安全,QML 编辑器可能无法提供自动补全或类型检查。
    • 只能在 QML 文件中访问一个特定的实例(通常是单例)。

在给出的例子中:

engine.rootContext()->setContextProperty("MyListModel", MyListModel::getInstance());

这里将 MyListModel 的单例实例设置为 QML 上下文的属性,名为 “MyListModel”。在 QML 文件中,可以直接通过 MyListModel 这个属性名来访问这个单例实例。

风险验证

//cpp
QScreen *screen = QGuiApplication::primaryScreen();
engine.rootContext()->setContextProperty("screen_WIDTH",800);
//qml
property int screen_width: 200
width: screen_WIDTH

此时的宽度是800还是200呢?是200

总结

  • qmlRegisterType 用于注册 C++ 类型,以便 QML 可以直接创建和使用这些类型的实例。
  • setContextProperty 用于将 C++ 对象或值设置为 QML 上下文的属性,以便 QML 可以直接访问它们。这通常用于单例或全局对象。
  • 不建议使用setContextProperty ,因为当全局和局部遇到重名时,会直接覆盖掉,这对于程序来说是非常危险的。
  • 性能方面qmlRegisterType 会稍好一点
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
QMLC++交互方法主要有以下几种: 1. 使用QObject::connect()函数连接QMLC++对象的信号和槽函数,实现数据的传递和交互。 2. 使用Q_INVOKABLE宏将C++函数声明为可在QML中调用的函数。这样,QML可以直接调用C++函数,实现数据的交互。 3. 使用Q_PROPERTY宏将C++对象的属性声明为可在QML中访问的属性。这样,QML可以直接访问C++对象的属性,实现数据的交互。 4. 使用QQmlContext类将C++对象注册QML中,并在QML中访问这些对象。这样,QML可以直接访问C++对象,实现数据的交互。 下面是一个具体的例子,展示了如何在QML中访问C++对象的属性和函数。 C++代码: ``` // MyObject.h #include <QObject> class MyObject : public QObject { Q_OBJECT Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged) public: explicit MyObject(QObject *parent = nullptr); int value() const; void setValue(int value); signals: void valueChanged(); private: int m_value; }; // MyObject.cpp #include "MyObject.h" MyObject::MyObject(QObject *parent) : QObject(parent) { m_value = 0; } int MyObject::value() const { return m_value; } void MyObject::setValue(int value) { if (m_value != value) { m_value = value; emit valueChanged(); } } ``` QML代码: ``` import QtQuick 2.0 Item { width: 200 height: 200 Text { text: "Value: " + myObject.value } Slider { anchors.top: text.bottom from: 0 to: 100 value: myObject.value onValueChanged: myObject.value = value } Connections { target: myObject onValueChanged: text.text = "Value: " + value } Component.onCompleted: { console.log("Value:", myObject.value) } } ``` 在这个例子中,我们创建了一个名为MyObject的C++对象,并将其注册QML中。MyObject类有一个名为value的属性和一个名为setValue的槽函数,用于设置属性值。在QML中,我们创建一个Slider和一个Text组件,用于显示和修改MyObject的value属性。我们还使用Connections组件将MyObject的valueChanged信号与Text的text属性绑定,以使其能够自动更新。最后,在Component.onCompleted信号处理程序中,我们打印MyObject的value属性的值,以验证其已成功从C++对象传递到QML界面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明教张公子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值