QT当中C++和QML的类型转换

令人头疼的QML和C++交互

最近公司使用了QML进行界面开发,开发界面确实很高效,而且QML对于触屏、动画的开发尤其友好,用我同事的话说,就是同样是画个矩形,填个颜色,QT需要实例化QPainter,之后画矩形,然后设置画笔,画刷,最后填颜色,QML直接一个Rectangle,甩你18条街。

但是QML也有不好用的地方,就是QML做界面是好做,各种底层功能的支持还是需要使用C++,这就带来了QML和C++的交互问题。

类型转化和糟心的QML文档

以前开发QT,使用QWidgets有什么问题只需要查找文档就好,而使用QML,感觉这个方法失效了,有些文档不仔细找,根本找不到。
这篇文件先说,C++和QML的类型转化问题。我个人总结的方法有两个:
1)使用C++和QML原生都支持的类型,进行参数传递;
2)将C++相关的类,注册进QML的组件或者QML的运行环境,之后进行调用。
由于第二种方法,其实和如何QML调用C++方法这个问题差不多,因此之后再进行讨论,本次只讨论法1.

类型转换-文档推荐用法

QT当中QML和C++类型转化的文档,可在帮助文档中直接搜索**“Data Type Conversion Between QML and C++”**。该文档详细描述了,QML和C++之间的类型转换,我个人总结如下。
首先是基本类型,QML和C++的类型之间有直接的对应关系,可直接进行交互。

Qt TypeQML Basic Type
boolbool
unsigned int, intint
doubledouble
float, qrealreal
QStringstring
QUrlurl
QColorcolor
QFontfont
QDateTimedate
QPoint, QPointFpoint
QSize, QSizeFsize
QRect, QRectFrect
QMatrix4x4matrix4x4
QQuaternionquaternion
QVector2D, QVector3D, QVector4Dvector2d, vector3d, vector4d
Enums declared with Q_ENUM() or Q_ENUMS()enumeration

以上的是基本的类型,而由基本类型组合成的复杂类型,如何进行交互呢?
由于JS是弱类型语言,因此QT使用了C++中的QVariant和JS当中的各种值建立了一种联系。对应的复杂类型之间的对应关系为:

Qt TypeQML Basic Type
QVariantListArray
QVariantMapObject

因此对于同种类型的组成的数组,可以使用QVariantList和QML进行交互,当然QVariantList可以承载不同的数据类型组成的列表,但这会引起歧义,而且很容易导致错误,所以不推荐使用这种方法。另外有以下的类型支持从C++转化为QML的array类型,但不支持从QML转化为C++,以下的类型包括:
QList, QList, QList, QList and QStringList, QVector, std::vector,QList,QVector,,std::vector,QVector,QVector,QVector,std::vector,std::vector,
std::vector。
对于不同类型的元素,推荐使用的方法是QVariantMap和QML中Object对应之间的转换。这样可以在转换之后,通过键值对进行查询,所以相比于QVariantList存储不同的类型,QVariantMap存储不同的类型,更加不同意出错。
有人要问了?C++当中的结构体,如何转到QML当中?
如果你要简单,不考虑效率,可以将结构体转化为QVariantMap之后,向QML发送,例如:

//转化为QVariantMap之前
struct Person
{
	int num;
	int age;
	QString name;
}
//转化为QVariantMap
{
	...
	QVariantMap personMap;
	personMap.insert("num",QVariant("num"));
	personMap.insert("age",QVariant("age"));
	personMap.insert("name",QVariant("name"));
	...
}
//之后在QML当中,直接像JS的Object一样调用
var num=person.num; 
//或者 var num=person["num"]

如果你考虑程序的运行效率,建议将结构体继承QObject写成类,编写对应的函数,之后注册到QML当中,这样可能效率高点?个人不太确定,主要是QObject夹杂太多东西。

夹杂私货

C++和QML还有一种比较好用的数据交换格式,那就是使用Json进行交互。
先说优点:
1)JS对于Json的天然支持,Json字符串可直接转化为JS的对象;
2)可以存储为文件,方便持久化,也方便排查错误;
缺点:
1)JS对于Json天然支持,而对应的C++需要编写解析或者生成Json字符串的方法(Qt解析Json,可以使用自带的QJsonValue,QJsonArray,QJsonObject等类);
2)效率较低,Json本身是字符串,而不是二进制,占体积大,需要解析,因此效率较低;
所以,你可以根据自己工程的实际情况考虑,是否需要使用Json进行数据交互。
关于QT当中C++和QML之间的转换,就说这些。有错误请指正,下次在写如何将C++的类,注册到QML当中。

  • 19
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值