上次分享的多线程方法是使用moveThread的方法,今天给大家分享下使用继承QThread的方式重写run()的方式创建多线程。
废话不多说直接上步骤:
步骤1:创建ReciveThread继承自QThread
#ifndef RECEIVETHERAD_H
#define RECEIVETHERAD_H
#include <QThread>
#include <QObject>
#include <QUdpSocket>
class ReceiveTherad :public QThread
{
Q_OBJECT;
public:
void SocketInit(QString ip,quint16 port);
explicit ReceiveTherad();
void run() override;
signals:
//日志记录信号
void LogAppend(const QString& text);
//数据接收信号
void dataReceived(QByteArray data);
public slots:
//数据获取函数
void DataReceive();
//数据接收处理槽函数
void DataHandle(QByteArray data);
private:
QUdpSocket *receiveSocket;
};
#endif // RECEIVETHERAD_H
步骤2:重写run函数并连接对应的信号进行接收
#include "ReceiveTherad.h"
ReceiveTherad::ReceiveTherad()
{
receiveSocket = new QUdpSocket();
}
//socket初始化函数
void ReceiveTherad::SocketInit(QString ip,quint16 port)
{
bool ret = false;
QHostAddress IP(ip);
ret = receiveSocket->bind(IP,port);
if(ret == true)
{
emit LogAppend("ReceiveTherad的socket绑定成功\n");
}
else
{
emit LogAppend("ReceiveTherad的socket绑定失败\n");
}
}
//重写run
void ReceiveTherad::run()
{
//socket不为空
if(nullptr != receiveSocket)
{
//UDP数据包被接收
connect(receiveSocket,&QUdpSocket::readyRead,this,&ReceiveTherad::DataReceive);
//连接自身的槽进行处理
connect(this,&ReceiveTherad::dataReceived,this,&ReceiveTherad::DataHandle);
}
else
{
emit LogAppend("receiveSocket未进行初始化为nullptr!!!!\n");
}
}
//数据接收函数
void ReceiveTherad::DataReceive()
{
while(receiveSocket->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(receiveSocket->pendingDatagramSize());
//将信息读取完成
receiveSocket->readDatagram(datagram.data(), datagram.size());
emit dataReceived(datagram);
}
}
//接收处理函数
void ReceiveTherad::DataHandle(QByteArray data)
{
emit LogAppend("线程ReceiveTherad收到数据");
QString str = "";
const uint8_t* receiveBuffer = reinterpret_cast<const uint8_t*>(data.constData());
int i = 0;
for(i=0; i< data.size(); i++)
{
//将接收到的数据按照16进制的方式显示
str += QString("%1").arg(static_cast<quint8>(receiveBuffer[i]), 2, 16, QLatin1Char('0'));
str += " ";
}
//将接收到的数据打印
emit LogAppend(str);
}
步骤3:在mainwindow.cpp初始化对应的线程和启动线程,我这边还是和之前 一样在点击绑定按钮的槽函数进行对应的初始化
这里我将之前写的方式和这次的方法分别封装了下
这里只需要start直接运行就好了
这边的主要逻辑和之前的逻辑差不多,只不过咱们的线程是一直运行的,同样的在判断接收到数据时进行数据的处理。
上效果:
下篇给大家分享如果关闭开启线程。