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()宏的原型:

[cpp] view plain copy
 
  1. Q_PROPERTY()(type name  
  2.   (READ getFunction [WRITE setFunction] |  
  3.              MEMBER memberName [(READ getFunction | WRITE setFunction)])  
  4.             [RESET resetFunction]  
  5.             [NOTIFY notifySignal]  
  6.             [REVISION int]  
  7.             [DESIGNABLE bool]  
  8.             [SCRIPTABLE bool]  
  9.             [STORED bool]  
  10.             [USER bool]  
  11.             [CONSTANT]  
  12.             [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

猜你喜欢

转载自www.cnblogs.com/gongkiro/p/13374812.html