QT下的多线程

一.多线程的使用:
继承QThread类,重写protected: void run();函数,则此run函数即为多线程将执行的函数,UI类组合此类,调用start()函数即开启此线程,并执行run函数

//.h
class test1 : public QThread  //!!
{
    Q_OBJECT
public:
    explicit test1(QObject *parent = nullptr);

signals:

public slots:
protected:
    void run();   //!!
    void read();
};

//.cpp
void test1::run()
{
    qDebug()<<QThread::currentThreadId()<<endl<<"threadnow";
    read();
}
void test1::read()
{
    qDebug()<<QThread::currentThreadId()<<endl<<"threadnow";
}

//.h
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    test1 *threadtest;  //!!

private slots:
    void on_button_begin_clicked();

private:
    Ui::MainWindow *ui;
};

//.cpp
void MainWindow::on_button_begin_clicked()
{
    qDebug()<<QThread::currentThreadId()<<endl;
    threadtest=new test1;  
    threadtest->start();  //!!
}

二.多线程在TCP通信中的应用

基本流程
1.新建一个类继承自QTcpServer,重写 protected: void incomingConnection(qintptr socketDescriptor); 当有一个连接到来时将自动调用此函数,所以应在此函数中创建线程。
2.新建一个类继承自QThread,重写 protected: void run(); ,将此类组合进 1 中的类,则当 1 中的类使用 start() 后将自动调用 run() 函数
3.在 2 的run()函数中使用waitForReadyRead()进行阻塞,从而获取数据
4.改进 3 的接收方式,新建一个类继承自QTcpSocket,在其中使用readyRead()与槽函数进行信息接收与发送

//myserver.h
#include <QTcpSocket>
#include <QTcpServer>
#include "serverthread.h"
class myserver:public QTcpServer
{
public:
    myserver();
protected:
    void incomingConnection(qintptr socketDescriptor);
};

//myserver.cpp
#include "myserver.h"
myserver::myserver()
{}
void myserver::incomingConnection(qintptr socketDescriptor)
{
    qDebug()<<"New Connect is connect"<<socketDescriptor;
    ServerThread * thread=new ServerThread();
    thread->write_ptr(socketDescriptor);
    thread->start();
}

//serverthread.h
#include <QThread>
#include <QTcpSocket>
#include <QTcpServer>
class ServerThread:public QThread
{
public:
    ServerThread();
    qintptr ptr;
    QTcpSocket * socket;
    void write_ptr(qintptr p);
protected:
    void run();
};

//serverthread.cpp
#include "serverthread.h"
ServerThread::ServerThread()
{}
void ServerThread::write_ptr(qintptr p)
{
    ptr=p;
}
void ServerThread::run()
{
    socket=new QTcpSocket();
    socket->setSocketDescriptor(ptr);//客户端的初始化
    if(socket->waitForConnected(10000)){
        qDebug()<<"Connect Success";
    }
    else{
        qDebug()<<"Connect Fail";
    }
    QByteArray data;
        forever {
            if (socket->waitForReadyRead())
            {
                qDebug()<<QThread::currentThreadId();
                data = socket->readAll();
                qDebug()<<data;
            }
            else {
                qDebug()<<"none";
                break;
            }
        }
}

//mainwindow.h
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void on_pushButton_clicked();
private:
    Ui::MainWindow *ui;
};

//mainwindow.cpp
void MainWindow::on_pushButton_clicked()
{
    qDebug()<<QThread::currentThreadId();
    myserver * server;
    server=new myserver();
    server->listen(QHostAddress::AnyIPv4,8888);
}

//mysocket.h
#include <QTcpSocket>
class mysocket:public QTcpSocket
{
    Q_OBJECT
public:
    mysocket();
public slots:
    void recvData(void);
private:
    int m_sockDesc;
};

//mysocket.cpp
mysocket::mysocket()
{
    connect(this, SIGNAL(readyRead()), this, SLOT(recvData()));
}
void mysocket::recvData()
{
    QByteArray buffer = this->readAll();
    if(!buffer.isEmpty())
    {//处理接收到的数据
        qDebug()<<buffer;
        QString data="send";
        this->write(data.toLatin1());
    }
}

//更改代码
void ServerThread::run()
{
    socket=new mysocket;
    socket->setSocketDescriptor(ptr);//客户端的初始化
    if(socket->waitForConnected(10000)){
        qDebug()<<"Connect Success";
    }
    else{
        qDebug()<<"Connect Fail";
    }
    this->exec();
}

三.借鉴出处
1.Qt Socket 多线程操作
2.Qt TCP通信,多线程服务器端

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值