0


【Qt】QML与C++的前后端交互与通信方法

文章目录

前言

学校的小学期要用到Qt,去做聊天室。

一般来说,Qt程序都是用自带的ui做的,但是那个ui其实也就差不多能用而已,要说好看,或者自由化,定制化,高上限,可移植,那还是QML技术更好。

Qt自带的ui和语言本身是有耦合的,而QML技术是纯粹的脚本语言,和C++前后端分离,而且还融合了JavaScript,所以可以实现强大的UI设计功能。

前后端分离,优点在于好看,缺点就是通信代价比较高,qt自带的有个ui指针,很容易操纵,但是QML是没有直接操纵的方法的。

用QML做项目一定要注重前后端通信,这也是和普通项目之间很大的区别,与消耗。

我这里注重讲解思路,具体如何操作,还请自行搜索QML与C++通信。

方法

虽说看起来是前后端分离了,但是既然QML是属于Qt系统的,那QML运行的时候本身也会以对象树的形式进入Qt系统(貌似叫元数据系统),这个系统可以将QML对象和Qt本身的C++类统一起来。

QML到C++的通信

信号与槽机制

Qt本来就有信号与槽机制,QML中的信号与槽机制类似,QML内可以定义信号,然后C++端写槽函数连接。

那么问题来了,connect有四个参数,分别是

  1. 发出信号的对象指针
  2. 信号(用qt4的写法)
  3. this(或者其他接受信号的指针)
  4. 槽函数(qt4写法)

参数1从哪里来?

很简单,在C++后台实例化一个QML节点就好了。

这种方法有一些缺点:

  1. 实例化QML节点需要逐层用findChild函数找,从父节点找到子节点,如果子节点是唯一且固定的还好,如果是list这种,很有可能就找不到了。
  2. 为了解决上面这种情况,通常需要将子节点信号移到父节点,但是这样的话,有时候调用就成了个问题,如果你不是专门研究这个问题的,有可能这里就会把你难住(对,说的就是我,所以我做小学期Qt聊天室的时候客户端有俩函数就是通过另一种方法调用的)
  3. 有时候还会出现连接不上的问题。通信出问题一般就是signal没发出来,或者发出来了但是节点选错了导致没有接收到,要么就是槽函数没写对。总之一系列流程走下来比较费神,而且有时候就算流程都ok,都有可能连不上。

优点嘛,没有,大概只是比较好理解罢了,以及适用于你其他类特别多的时候,如果别的类特别多,那你在QML中就得实例化很多C++对象,不方便。

不过呢,看到后面你就会明白,这个方法还是得学。

往QML中传C++对象指针

另一种更简单的方法,就是在C++中实例化对象,把指针传到QML里。同时把C++对象里的方法进行特殊声明(比如加Q_INVOKABLE关键字或者public slots)

通常,人们都是直接用new构造函数,这样把实例化和传指针一起了,实际上,你完全可以先实例化,然后再传指针进去。

进去以后虽然是指针,但是用的时候是用.符号去取成员的,这个对象会成为QML全局的C++对象,这样,要调用某个类的方法就直接用这个类的QML实例对象就ok。

缺点。刚开始理解可能摸不着头脑,而且没法用C++中的变量。(实际上好像还可以注册变量,但是我懒得去搜了)

优点很大,就是写起来很快,很爽。推荐用这个。

注册类

和上面实例化比较类似。实例化是在C++实例化,然后传指针进去,而注册类是在QML中实例化,用法应该类似,我没有去细究(都有传指针了还要什么实例化)

C++到QML的通信

网上的C++端到QML的通信只有一种方法,就是调用QMetaObject::revokeMethod回调函数。
注意!所有的参数一定要设成QVariant类,因为QML是js语法,里面都是弱类型,QVariant和js的var对应,否则调用不了,就算你知道是int,你也得写QVariant。

这里可以看出,其实学一学第一种通信还是有好处的,因为你要调用就要去找到QML节点指针,这和第一种通信的前半步是一样的。

好在呢,父节点的QML函数可以对子节点产生作用,也不用担心出现信号的那种父子节点问题。所以这一种方法就可以通杀,调用起来也很简单,不用折腾什么信号的,和前面QML到C++中传指针的方法一样的方便。

标签: qt c++ 交互

本文转载自: https://blog.csdn.net/weixin_50295745/article/details/126529244
版权归原作者 亦梦亦醒乐逍遥 所有, 如有侵权,请联系我们删除。

“【Qt】QML与C++的前后端交互与通信方法”的评论:

还没有评论