QML和C++交互的方法1--------实现可以被QML访问的C++类
总所周知,逻辑是要和界面分开的
1. 创建继承QObject的类
右键工程/add new/C++/C++ class/
选择base class为:QObject
取名:Gemini 随便吧
2. 创建信号和槽
signal:begin()
槽:doSomething()
槽必须是protected或者public,后面跟上slots;
信号在C++中使用时,在需要触发信号的的地方 加上 emit begin(),而在QML中则是一个普通的函数,
用法同函数一样,信号处理器形式为on<Signal>比如【onBegin】,Signal首字母大写。
信号不支持重载,多个信号的名字相同而参数不同时,能够被识别的只是最后一个信号,与信号的参数无关。
3. 在main.cpp中注册C++类
注册C++类通常用到的接口为qmlRegisterType(),四个入参,分别是
template<typename T> int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);
uri是需要导入到QML中的库名,
versionMajor和versionMinor是其版本数字,
qmlName是在QML中可以使用的类型名
在QML中使用import Union.Lotto.Gemini 1.0导入C++类
4. 在QML中导入C++类并使用
import Union.Lotto.Gemini 1.0导入Gemini
插件id为gemini的类型,相应begin()信号的动作为onBegin;在这个时候Gemini已经是QML中的一个类型了
设定鼠标消息onClick(),动作为gemini.begin(),既是id为gemini的onBegin
在触发鼠标onClick()时,就会执行Gemini中的doSomething函数
如此:在QML中就能访问C++中信号和槽
5.枚举的访问
同槽一样,在QML中访问的枚举需要定义为public或者protected,另额外需要使用枚举宏修饰枚举
Q_ENUMS(BALL_COLOR)
定义成员变量BALL_COLOR m_ballColor,并且初始化,修改doSomething函数
修改qml中的onBegin信息
在qml中访问C++中的形式:C++类名.枚举值;如:Gemini.BALL_COLOR_RED
如此:在QML中就能访问C++中枚举
6.成员函数
Gemini类中添加了成员函数stop(),在QML中访问的前提是public或protected成员函数,且使用Q_INVOKABLE宏,位置在函数返回类型的前面。
在qml中访问形式: C++类名.stop(), 如:gemini.stop()
如此:在QML中就能访问C++中成员函数
7.C++类的属性
Gemini类中添加了Q_PROPERTY()宏,用来在QObject派生类中声明属性,这个属性如同类的数据成员一样,但它又有一些额外的特性可通过Qt元对象系统来访问。
下面是Q_PROPERTY()宏的原型:
- Q_PROPERTY()(type name
- (READ getFunction [WRITE setFunction] |
- MEMBER memberName [(READ getFunction | WRITE setFunction)])
- [RESET resetFunction]
- [NOTIFY notifySignal]
- [REVISION int]
- [DESIGNABLE bool]
- [SCRIPTABLE bool]
- [STORED bool]
- [USER bool]
- [CONSTANT]
- [FINAL])
属性的type、name是必需的,其它是可选项,常用的有READ、WRITE、NOTIFY。属性的type可以是QVariant支持的任何类型,也可以是自定义类型,包括自定义类、列表类型、组属性等。另外,属性的READ、WRITE、RESET是可以被继承的,也可以是虚函数,这些特性并不常用。
READ:读取属性值,如果没有设置MEMBER的话,它是必需的。一般情况下,函数是个const函数,返回值类型必须是属性本身的类型或这个类型的const引用,没有参数。
WRITE:设置属性值,可选项。函数必须返回void,有且仅有一个参数,参数类型必须是属性本身的类型或这个类型的指针或引用。
NOTIFY:与属性关联的可选信号。这个信号必须在类中声明过,当属性值改变时,就可触发这个信号,可以没有参数,有参数的话只能是一个类型同属性本身类型的参数,用来记录属性改变后的值。
Q_PROPERTY()的详细用法可参考如下网址:
http://doc.qt.io/qt-5/properties.html#qt-s-property-system
在qml中修改
gemini.ballNumber = 10 会调用setBallNumber
setBallNumber被调用时触发信号ballNumberChanged会动作在qmlGemini类型中的onBallNumberChanged
console.log("new ball number is", ballNumber)会调用ballNumber
鼠标onClick()后的动作如下:
如此:在QML中就能访问C++中属性
8.在C++中改变属性
在C++中定义个定时器,每1s触发修改m_ballNumber
如此在qml Gemini类型中的属性也会被相应修改
同性交友平台:https://github.com/GongKiro/gongkiro_code
MARK:本文基本是参照了https://www.cnblogs.com/findumars/p/6090850.html重新写了一遍,
比较肤浅,算是做个笔记了,另外一种交互的办法也可以在该文中知道。
THX