C++与QML交互(一)

C++与QML交互,实际项目中采用的是QML和js开发界面,C++实现功能逻辑,故C++与QML交互大多是QML调用C++,交互内容主要有QML调C++接口、QML接收C++的信号、QML使用C++对象的属性等。QML要调用C++必须基于元对象系统,C++类需要继承自QObject,可以通过注册到QML类型系统中使用,也可以直接暴露C++对象给QML进行使用

注册c++类型

C++类可以注册为可实例化的QML类型,这样它就可以像QML代码中的任何普通QML对象类型一样被实例化和使用

1、qmlRegisterType

qmlRegisterType<TestManager>("TestManager", 1, 0, "TestManager");
import TestManager 1.0

2、宏QML_ELEMENT

该方式是通过构建系统进行注册,如果有多个对象需要注册,这种方式还是比较简便的

 class Slider : public QObject
 {
     Q_OBJECT
     QML_ELEMENT
     ...
 }

在pro文件中定义名称及版本

 CONFIG += qmltypes
 QML_IMPORT_NAME = com.mycompany.qmlcomponents
 QML_IMPORT_MAJOR_VERSION = 1

调用方式和上面的一样

 import com.mycompany.qmlcomponents 1.0

 Slider {
     // ...
 }

QML使用的名称默认和类名一致,若要另外指定名称,则可以使用QML_NAMED_ELEMENT

3、单例属性qmlRegisterSingletonInstance

这种方式我也没用过,就不展开了

暴露C++对象

使用QML引擎添加c++对象为上下文属性

TestManager manager;
engine.rootContext()->setContextProperty("manager", &manager);

manager在QML中将作为全局对象使用

Rectangle {
    width: 100
    height: 100
    color: manager.color
}

交互方式

接口调用

使用Q_INVOKABLE对接口函数进行声明,该宏的作用是允许通过元对象系统进行调用

Q_INVOKABLE void add(int a, int b);

或者是public slots:

public slots:
    void add2(int a, int b);

接收信号

从QML代码可以访问任何从QObject派生的类型的公共信号

signals:
    void sendAdd(int val);

QML绑定接收,函数名称使用on+信号名称,信号名称需大写

Connections {
     target: manager
     function onSendAdd(val) {
         console.log("add value" + val)
     }
}

属性

使用Q_PROPERTY添加属性

Q_PROPERTY(QColor color MEMBER m_color NOTIFY colorChanged)

QML调用

Manager {
    id: manager
    color: "red"
}

具体可参考我的令一篇文章关于属性的使用

交互的方式还有枚举类型,目前在项目中用得不多,就不做记录了

C++与QML数据类型转换

当数据值在QML和C++之间交换时,它们被QML引擎转换成适合在QML或C++中使用的正确数据类型。这要求交换的数据是引擎可识别的类型。

QML引擎为大量Qt C++数据类型提供了内置支持。

基本的数据类型有

Qt TypeQML Basic Type
boolbool
unsigned int, intint
doubledouble
float, qrealreal
QStringstring
QUrlurl
QColorcolor
QFontfont
QDateTimedate
QPointQPointFpoint
QSizeQSizeFsize
QRectQRectFrect
QMatrix4x4matrix4x4
QQuaternionquaternion
QVector2DQVector3DQVector4Dvector2dvector3dvector4d
Enums declared with Q_ENUM() or Q_ENUMS()enumeration

数据所有权

当数据从C++转移到QML时,数据的所有权总是属于C++。此规则的例外情况是当从显式C++方法调用返回QObject时:在这种情况下,QML引擎会假定对象的所有权,除非通过调用指定了qqmlengine::CppOwnership的qqmlengine::setObjectOwnership()已将对象的所有权显式设置为保留在C++中。

此外,QML引擎尊重Qt C++对象的正常QObject父所有权语义,并且永远不会删除具有父对象的QObject实例。

这一点很关键,很多时候会出现c++释放了相关的数据,QML界面又进行释放,就会出现崩溃的情况,不清楚的就出现莫名其妙的崩溃,QML又和c++不一样,这种情况实属不好定位

结语

关于C++与QML交互的内容其实是挺多,这里只介绍常见的用法和注意点,想要了解更多可以看看官方文档

本文章介绍的demo地址

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QMLC++ 交互的过程一般分为以下几个步骤: 1. 定义 C++ 类并注册到 QML 中 你需要在 C++ 中定义一个类,该类封装了你想要实现的功能。同时,你需要使用 `qmlRegisterType` 函数将该类注册到 QML 中,以便在 QML 中使用该类。 例如,你可以定义一个名为 `MyClass` 的类,并将其注册到 QML 中: ```cpp class MyClass : public QObject { Q_OBJECT public: Q_INVOKABLE int myFunction(int arg) { // 实现你的功能 } }; qmlRegisterType<MyClass>("com.example", 1, 0, "MyClass"); ``` 在上面的代码中,`Q_INVOKABLE` 用于声明 `myFunction` 函数可从 QML 中调用,`qmlRegisterType` 函数用于将 `MyClass` 类注册到 QML 中。`"com.example"` 表示注册的命名空间,`1` 和 `0` 表示主版本号和次版本号,`"MyClass"` 是在 QML 中使用的类名。 2. 在 QML 中使用 C++ 类 在 QML 中使用 C++ 类时,你需要使用 `import` 语句导入该类所在的命名空间。然后,你可以通过该命名空间来访问该类。例如: ```qml import com.example 1.0 MyClass { id: myClass } Button { onClicked: { var result = myClass.myFunction(42) // 处理返回值 } } ``` 在上面的代码中,`import` 语句用于导入 `com.example` 命名空间,`MyClass` 用于创建一个 `MyClass` 实例,`id` 属性用于设置实例的标识符,`Button` 用于创建一个按钮,`onClicked` 事件处理程序中调用了 `myFunction` 函数,并处理了它的返回值。 3. 在 C++ 中访问 QML 中的对象 如果你需要从 C++ 中访问 QML 中的对象,你可以使用 `QQuickItem` 类提供的 `findChild` 函数。例如: ```cpp QQuickItem *item = qmlEngine.rootObjects().value(0)->findChild<QQuickItem*>("myItem"); if (item) { // 处理 item 对象 } ``` 在上面的代码中,`qmlEngine.rootObjects()` 函数返回 QML 引擎中所有的根对象,`value(0)` 返回第一个根对象,`findChild` 函数用于查找名为 `"myItem"` 的子对象。 以上就是 QMLC++ 交互的基本步骤。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值