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

本节学习一下C++和qml传输数据时的类型转换,可能会比较枯燥,其实也没什么可以详细说的,跑一遍代码学习一下就行。
一、代码演示:
先自定义一个C++类:
#ifndef CPPCLASS_H
#define CPPCLASS_H#include <QObject>
#include <QtQml>
#include <QColor>
#include <QFont>class CppClass : public QObject
{Q_OBJECT
// QML_ELEMENTpublic: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
#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;
}
然后我们注册一下可实例化类:
#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:
import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Controls 2.12
import com.mycompany 1.0Window {visible: truewidth: 640height: 480title: qsTr("QmlBasicDataTypes")CppClass{id: cppClassIdonSendInt: 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 objectconsole.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 = colorparambuttonId.font = fontparam}onSendDate: (dateparam)=>{console.log("Received date :" + dateparam + ", type is :" + typeof dateparam)//Extract infoconsole.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 infoconsole.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 infoconsole.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 ifnoconsole.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: buttonIdtext: "test"onClicked: {cppClassId.cppSlot()cppClassId.receivePoint(Qt.point(200, 300));cppClassId.receiveRect(Qt.rect(20, 30, 200, 300));}}Rectangle{id: rectIdy: buttonId.y + buttonId.heightwidth: 200height: 200color: "black"radius: 20}
}
二、运行结果
我们的当前功能是,点击按钮触发C++的数据发送和qml的数据发送:
onClicked: {cppClassId.cppSlot()cppClassId.receivePoint(Qt.point(200, 300));cppClassId.receiveRect(Qt.rect(20, 30, 200, 300));
}
点击按钮后,打印的信息比较多,我直接截图吧。


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