前言
在QML和C++的交互过程中,时常会发送和传递不同类型的数据,这个时候我们需要关注数据类型的转换,以免发生不必要的错误。
从C++侧传输数据到QML侧后,数据会变成对于QML而言的数据类型,尽管他们都被成为布尔值,或浮点数什么的。大多数情况下,去掉Q,就是qml的类型名字了。

本节学习一下C++和qml传输数据时的类型转换,可能会比较枯燥,其实也没什么可以详细说的,跑一遍代码学习一下就行。
一、代码演示:
先自定义一个C++类:
cpp
#ifndef CPPCLASS_H
#define CPPCLASS_H
#include <QObject>
#include <QtQml>
#include <QColor>
#include <QFont>
class CppClass : public QObject
{
Q_OBJECT
// QML_ELEMENT
public:
explicit CppClass(QObject *parent = nullptr);
signals:
void sendInt(int parama);
void sendDouble(double param);
void sendBoolRealFloat(bool boolParam, qreal realparam, float floatparam);
void sendStringUrl(QString stringparam, QUrl urlparam);
void sendColorFont(QColor colorparam,QFont fontparam);
void sendDate( QDate dateparam);
void sendPoint( QPoint pointparam, QPointF pointfparam);
void sendSize( QSize sizeparam , QSizeF sizefparam);
void sendRect(QRect rectparam, QRectF rectfparam);
public slots:
void cppSlot();
void receivePoint(QPoint point);
void receiveRect(QRect rect);
};
#endif // CPPCLASS_H
cpp
#include "cppclass.h"
#include <QDebug>
CppClass::CppClass(QObject *parent) : QObject(parent)
{
}
void CppClass::cppSlot()
{
qDebug()<<"cppSlot called";
emit sendInt(123);
emit sendDouble(123.45);
emit sendBoolRealFloat(true, 2.11, 3.3);
emit sendStringUrl("String from C++",QUrl("http://ww.blikoontech.com"));
emit sendColorFont(QColor(123,20,30),QFont("Times", 20, QFont::Bold));
emit sendDate(QDate (1995, 4, 17));
emit sendDate(QDate::currentDate());
emit sendPoint(QPoint(100,200),QPointF(45.54,87.34));
emit sendSize(QSize(200,500),QSizeF(200.45,500.45));
emit sendRect(QRect(100,100,300, 300),QRectF(105.5,105.5,200.4,200.4));
}
void CppClass::receivePoint(QPoint point)
{
qDebug()<<"receivePoint: "<< point;
}
void CppClass::receiveRect(QRect rect)
{
qDebug()<<"receiveRect: "<< rect;
}
然后我们注册一下可实例化类:
cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <cppclass.h>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<CppClass>("com.mycompany", 1, 0, "CppClass");
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
最后是qml:
cpp
import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.12
import com.mycompany 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("QmlBasicDataTypes")
CppClass{
id: cppClassId
onSendInt: function(param){
console.log("Received int: " + param + ", type is : " + typeof param)
}
onSendDouble: function(param){
console.log("Received double: " + param + ", type is : " + typeof param)
}
onSendBoolRealFloat: function(boolParam, realparam, floatparam){
console.log("Received bool: " + boolParam + ", type is : " + typeof boolParam)
console.log("Received real: " + realparam + ", type is : " + typeof realparam)
console.log("Received float: " + floatparam + ", type is : " + typeof floatparam)
}
onSendStringUrl: (stringparam, urlparam)=>{
console.log("Received string :" + stringparam + ", type is :" + typeof stringparam)
console.log("Received url :" + urlparam + ", type is :" + typeof urlparam)
}
onSendColorFont: ( colorparam, fontparam)=>{
console.log("Received color :" + colorparam + ", type is :" + typeof colorparam)
console.log("Received font :" + fontparam + " , type is :" + typeof fontparam.family)
//Access properties of object
console.log("Color components : red :" + colorparam.r + " , green :" + colorparam.g + ", blue :"+ colorparam.b);
console.log("Font family :" +fontparam.family)
console.log("Font bold:" + fontparam.bold)
rectId.color = colorparam
buttonId.font = fontparam
}
onSendDate: (dateparam)=>{
console.log("Received date :" + dateparam + ", type is :" + typeof dateparam)
//Extract info
console.log("Year is :" + dateparam.getFullYear())
console.log("Month is :" + dateparam.getUTCMonth())
console.log("Day of week is :" + dateparam.getDay())
console.log("The day of moth is :" + dateparam.getDate())
}
onSendPoint: (pointparam, pointfparam)=>{
console.log("Received point:" + pointparam +",type is :" +typeof pointparam)
console.log("Received pointf :" + pointfparam + ", type is :" + typeof pointfparam)
//Extract info
console.log("point.x:" + pointparam.x + "\npoint.y :"+ pointparam.y +"\npointf.x :"+ pointfparam.x +"\npointf.y :"+ pointfparam.y)
}
onSendSize: (sizeparam , sizefparam)=>{
console.log("Received size :" + sizeparam + ", type is :" + typeof sizeparam)
console.log("Received sizef :" + sizefparam + ", type is :" + typeof sizefparam)
//Extract info
console.log("size.width :" + sizeparam.width +"\nsize.height :"+ sizeparam.height +"\nsizef.witdth:"+ sizefparam.width + "\nsizef.height :"+ sizefparam.height)
}
onSendRect: (rectparam, rectfparam)=>{
console.log("Received rect :" + rectparam + ", type is :" + typeof rectparam)
console.log("Received rectf :" + rectfparam + ", type is :" + typeof rectfparam)
//Extract ifno
console.log("rect.x:"+ rectparam.x + "\nrect.y :"+ rectparam.y +"\nrect.width:" + rectparam.width +"\nrect.height:"+ rectparam.height )
console.log("\n\n\nrectf.×:"+ rectfparam.x + "\nrectf.y :"+ rectfparam.y +"\nrectf.width:" + rectfparam.width +"\nrectf.height:"+ rectfparam.height)
}
}
Button{
id: buttonId
text: "test"
onClicked: {
cppClassId.cppSlot()
cppClassId.receivePoint(Qt.point(200, 300));
cppClassId.receiveRect(Qt.rect(20, 30, 200, 300));
}
}
Rectangle{
id: rectId
y: buttonId.y + buttonId.height
width: 200
height: 200
color: "black"
radius: 20
}
}
二、运行结果
我们的当前功能是,点击按钮触发C++的数据发送和qml的数据发送:
cpp
onClicked: {
cppClassId.cppSlot()
cppClassId.receivePoint(Qt.point(200, 300));
cppClassId.receiveRect(Qt.rect(20, 30, 200, 300));
}
点击按钮后,打印的信息比较多,我直接截图吧。


三、总结
C++和qml之间的数据类型转换是需要注意的一个问题。我没有什么太多可说的,后续还有其他的类型需要学习。