封装C++类给QML使用

一、常用宏

1、信号与槽

C++类中的信号与槽都可以在QML中访问

2、C++类的成员函数,Q_INVOKABLE

Q_INVOKABLE void function();

3、C++类的枚举,Q_ENUMS

Q_ENUMS (enumName)

4、C++的属性,Q_PROPERTY

Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged

 

二、定义QObject子类

Myudp.h

#ifndef MYUDP_H
#define MYUDP_H

#include <QObject>
#include <QUdpSocket>
class Myudp : public QObject
{
    Q_OBJECT
public:
    explicit Myudp(QObject *parent = nullptr);
signals:
    void rcvdDataSignal(const QByteArray&);
    void sendedSignal(const QString&);//发送成功
public slots:
    void initUdpSlot();
    void requestSlot();
    void sendSlot(const QByteArray&);
private:
    QUdpSocket* udpClient = nullptr;
    const QString localIp="127.0.0.1";
    const quint16 localPort=8080;
    const QString aimIp="127.0.0.1";
    const quint16 aimPort=8888;
};

#endif // MYUDP_H

Myudp.cpp

#include "myudp.h"

Myudp::Myudp(QObject *parent) : QObject(parent)
{

}

/***********************************************/
// z 函数名称:初始化
// h 函数作用:NULL
// u 函数参数:NULL
// x 函数返回值:NULL
// y 备注:NULL
/***********************************************/
void Myudp::initUdpSlot()
{
    if(udpClient == nullptr)
    {
        udpClient = new QUdpSocket(this);
        udpClient->bind(QHostAddress(localIp),localPort);
        QObject::connect(udpClient,SIGNAL(readyRead()),this,SLOT(requestSlot()));
    }
}

/***********************************************/
// z 函数名称:接收数据
// h 函数作用:NULL
// u 函数参数:NULL
// x 函数返回值:NULL
// y 备注:NULL
/***********************************************/
void Myudp::requestSlot()
{
    if(udpClient->pendingDatagramSize() == 0)
    {
        return;
    }
    QByteArray ba;
    ba.resize(udpClient->pendingDatagramSize());
    QHostAddress tempHost("");
    quint16 port = 0;
    udpClient->readDatagram(ba.data(),udpClient->pendingDatagramSize(),&tempHost,&port);

    emit rcvdDataSignal(ba);
}

/**
 *函数名:发送槽函数
 *函数参数:NULL
 *函数作用:NULL
 *函数返回值:NULL
 *备注:NULL
 */
void Myudp::sendSlot(const QByteArray &info)
{
    if(info.size()==udpClient->writeDatagram(info,QHostAddress(aimIp),aimPort))
    {
        QString str = info.toHex().toUpper();
        emit sendedSignal(str);
    }
}

 

三、方法1:注册Myudp类,在QML中实例化【注册C++类】

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QThread>
#include "myudp.h"
#include <QQuickView>
#include <QQmlContext>
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    qmlRegisterType<Myudp>("Myudp.module",1,0,"Myudp");
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import Myudp.module 1.0
import QtQuick.Controls 2.2
Window {
    id: root
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Myudp{
        id:udp
    }
    Row{
        Button {
            id: connetBtn
            text: qsTr("连接")
            onClicked: {
                udp.initUdpSlot()
            }
        }

        Button {
            id: sendBtn
            text: qsTr("发送")
            onClicked: {
                udp.sendSlot("123")
            }
        }
    }
}

 

四、方法2:注册Myudp对象,在QML直接使用【设置上下文属性】

 main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QThread>
#include "myudp.h"
#include <QQuickView>
#include <QQmlContext>
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);


    Myudp udp;

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("udp",&udp);//注册对象
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
    id: root
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Row{
        Button {
            id: connetBtn
            text: qsTr("连接")
            onClicked: {
                udp.initUdpSlot()
            }
        }

        Button {
            id: sendBtn
            text: qsTr("发送")
            onClicked: {
                udp.sendSlot("123")
            }
        }
    }
}

 

 

ps:举例使用QTimer

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QThread>
#include "myudp.h"
#include <QQuickView>
#include <QQmlContext>
#include <QTimer>
int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);



    qmlRegisterType<QTimer>("QTimer.module",1,0,"Timer");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QTimer.module 1.0
import QtQuick.Controls 2.2
Window {
    id: root
    visible: true
    width: 100
    height: 100
    title: qsTr("")
    Rectangle {
        id: lamp
        width: 40
        height: 40
        radius: 5
        color: "red"
        anchors.centerIn: parent
    }
    Timer {
        id:countDown
        interval: 1000
        property bool isChange: true
        onTimeout:  {
            isChange = !isChange
            if(isChange){
                lamp.color = "black"
            }
            else{
                lamp.color = "red"
            }
        }
        Component.onCompleted: {
            countDown.start()
        }
    }
}

效果:每隔一秒修改背景色

 果然采用GPU渲染:

 

posted @ 2019-07-24 23:28  朱小勇  阅读(2031)  评论(0编辑  收藏  举报