给QML传递在C++中自定义数据类型(Class)的数据

在C++中,结构体/类均可用于自定义数据类型,也正是这些特性让我们的程序变得更加的灵活。但如果是在C++中定义了某一个数据类型Class,使用该数据类型进行计算并需要在QML中使用该计算结果时怎么办呢?Qt中C++和QML的数据自动转化支持的数据类型:

 

除以上的数据类型外,C++传递给QML的值是无法被QML识别的,也就是自定义的数据类型是无法通过编译系统自动转化的。因此只能采用发送信号携带参数或者使用Q_INVOKABLE宏在qml中获得返回值,将该自定义数据类型的数据以对象的形式传递给QML。

例如,我自定义了数据类型PointDataF,该数据类型包含了三个属性(方位,距离,高度),用于记录空间中的位置信息,构建该数据类:(注意:该自定义数据类型不能继承自QObject,同时也不能使用Q_OBJECT宏,因为该数据类型如果我们需要以信号的方式发送出去,而不是在类中使用信号与槽(我理解就是不能自己的爸爸是自己)!因此使用Q_GADGET宏单纯的实现反射功能

PointDataF.h:

#ifndef POINTDATAF_H
#define POINTDATAF_H

#include <QMetaType>
#include <QDebug>
class PointDataF
{
    Q_GADGET
    Q_PROPERTY(qreal azimuth READ azimuth WRITE setAzimuth)
    Q_PROPERTY(qreal distance READ distance WRITE setDistance)
    Q_PROPERTY(qreal height READ height WRITE setHeight)
public:
    PointDataF();
    PointDataF(const PointDataF& other);
    ~PointDataF();
    PointDataF(const qreal &azimuth, const qreal &distance,const qreal& height);

    qreal azimuth() const;
    qreal distance() const;
    qreal height() const;

    void setAzimuth(qreal);
    void setDistance(qreal);
    void setHeight(qreal);
private:
    qreal Azimuth;
    qreal Distance;
    qreal Height;

};

Q_DECLARE_METATYPE(PointDataF);
QDebug operator<<(QDebug dbg, const PointDataF &pointdata);

#endif // POINTDATAF_H

PointDataF.cpp:

#include "pointdataf.h"

PointDataF::PointDataF(){

}

PointDataF::PointDataF(const PointDataF& other){
    Azimuth = other.Azimuth;
    Distance = other.Distance;
    Height = other.Height;
}

PointDataF::PointDataF(const qreal &azimuth, const qreal &distance,const qreal& height){
    Azimuth = azimuth;
    Distance = distance;
    Height = height;
}

PointDataF::~PointDataF(){

}

qreal PointDataF::azimuth() const{
    return Azimuth;
}

qreal PointDataF::distance() const{
    return Distance;
}

qreal PointDataF::height() const{
    return Height;
}

void PointDataF::setAzimuth(qreal a)
{
    Azimuth = a;
}

void PointDataF::setDistance(qreal d)
{
    Distance = d;
}

void PointDataF::setHeight(qreal h)
{
    Height = h;
}

QDebug operator<<(QDebug dbg, const PointDataF &pointdata){
    dbg.space()<<"Azimuth:"<<pointdata.azimuth()<<"Distance:"<<pointdata.distance()<<"Height:"<<pointdata.height();
    return dbg.maybeSpace();
}

下面分别阐述下使用信号传递与使用Q_INVOKABLE宏的方法:

(1)使用信号与槽机制传递:

在C++中使用该数据类型进行计算处理,并将处理后的数据通过信号发送给QML,注意:在发送信号前需要将PointDataF注册到元系统中去,就可以当作信号参数发送啦!

.cpp:

qRegisterMetaType<PointDataF>("PointDataF");
PointDataF pointDataF(1.2,1.5,400.0);
qDebug()<<"PointDataF:"<<pointDataF;
emit test(pointDataF);

.qml:

Connections{
        target: offlinethread
        onTest:{
            console.log(pointDataF.azimuth,pointDataF.distance,pointDataF.height,typeof(pointDataF))
        }
    }

(2)使用Q_INVOKABLE宏将函数注册到元对象系统方法:

在.h头文件中使用宏:

Q_INVOKABLE PointDataF getPointDataF();

.cpp:

PointDataF OffLineThread::getPointDataF()
{
    PointDataF pointDataF(1.2,1.5,400.0);
    qDebug()<<"PointDataF:"<<pointDataF;
    return pointDataF;
}

.qml:

var pointDataF = offlinethread.getPointDataF()
console.log(pointDataF.azimuth,pointDataF.distance,pointDataF.height,typeof(pointDataF))

程序输出结果:

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页