一、常用宏
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渲染: