Qt thread communication custom data

Passing data between Qt threads

Because Qt has a signal and slot mechanism, it is particularly convenient to transfer data between threads

A few notes before starting

1. The slot parameter must be Qt's built-in metadata type, such as int , double, QString, etc.

2. If it is a custom data type, it must be registered as Qt metadata before connect ( qRegisterMetaType ).

3. When passing parameters between threads, it is best to add the const qualifier before the parameters. After adding const , the life cycle of the parameters will be as long as the life cycle of the program, so as to avoid the parameter passing process, the parameters have reached the life cycle and become invalid .

private:
    readdata(const QString data);
    readdata1(const ThreadCommunicate::mydata);

Examples:

Metadata between the child thread and the main thread (QString)

client.h:

#ifndef CLIENT_H
#define CLIENT_H

#pragma execution_character_set("utf-8")

#include <QMainWindow>
#include <QThread>

#include <QUdpSocket>
#include <QHostAddress>
#include "threadcommunicate.h"

namespace Ui {
class Client;
}

class Client : public QMainWindow
{
    Q_OBJECT

public:
    explicit Client(QWidget *parent = nullptr);
    ~Client();

    struct mydata{
        QString info;
        int flag;
    };

private slots:
    void on_pushButton_send_clicked();

    void readData();

    void on_pushButton_init_clicked();

    void on_pushButton_thread_clicked();

    void readdata(const QString data);

    void on_pushButton_thread_2_clicked();

    void readdata1(const ThreadCommunicate::mydata);

signals:
    void sendsignal(); //发送信号给子线程,要求发送string字符串传过来

    void sendsignal1(); //发送信号给子线程,要求发送自定义数据过来

private:
    Ui::Client *ui;

    QThread *subthread;

    QUdpSocket *udp;

    ThreadCommunicate *tc;
};

#endif // CLIENT_H

client.cpp:

#include "client.h"
#include "ui_client.h"

Client::Client(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Client)
{
    ui->setupUi(this);
    tc = new ThreadCommunicate();
    QThread *thread = new QThread();
    tc->moveToThread(thread);
    thread->start();
    connect(this, &Client::sendsignal, tc, &ThreadCommunicate::senddata);
    connect(tc, &ThreadCommunicate::sendData, this, &Client::readdata);
    qRegisterMetaType<mydata>("mydata");
    connect(this, &Client::sendsignal1, tc, &ThreadCommunicate::senddata1);
    connect(tc, &ThreadCommunicate::sendData1, this, &Client::readdata1);
}

Client::~Client()
{
    delete ui;
}


void Client::on_pushButton_send_clicked()
{
    for(ushort port=6666; port<6670; port++){
    udp->writeDatagram(ui->textEdit_send->toPlainText().toUtf8(), QHostAddress("127.0.0.1"), port);
    }
}

void Client::readData()
{
    qDebug()<<"有节点发来消息";
    QByteArray data;
    data.resize(int(udp->pendingDatagramSize()));
    qint64 len =  udp->readDatagram(data.data(), data.size());
    qDebug()<<"len:"<<len;
    QString message = data.data();
    if(len != -1 || len != 0){
        ui->textEdit_receive->append(message);
    }
    qDebug()<<"message:"<<message;
}

void Client::on_pushButton_init_clicked()
{
    udp = new QUdpSocket();
    ushort port = ui->lineEdit->text().toUShort();
    udp->bind(QHostAddress::Any, port);
    connect(udp, &QUdpSocket::readyRead, this, &Client::readData);
    ui->pushButton_init->setEnabled(false);
    qDebug()<<port;
}

void Client::on_pushButton_thread_clicked()
{
    emit sendsignal();
}

void Client::readdata(const QString data)
{
    ui->textEdit_thread->append(data);
}

void Client::on_pushButton_thread_2_clicked()
{
    emit sendsignal1();
}

void Client::readdata1(const ThreadCommunicate::mydata md)
{
    ui->textEdit_thread_2->append(QString::number(md.flag)+" "+md.info);
}

ThreadCommunicate.h:

#ifndef THREADCOMMUNICATE_H
#define THREADCOMMUNICATE_H
#pragma execution_character_set("utf-8")
#include <QObject>
#include <QThread>

class ThreadCommunicate : public QObject
{
    Q_OBJECT
public:
    ThreadCommunicate(QObject *parent = nullptr);

    struct mydata{
        QString info;
        int flag;
    };

public slots:
    void senddata();

    void senddata1();

signals:
    void sendData(const QString data); //发送字符串给主线程

    void sendData1(const ThreadCommunicate::mydata); //发送自定义数据给主线程

};

#endif // THREADCOMMUNICATE_H

ThreadCommunicate.cpp:

#include "threadcommunicate.h"

ThreadCommunicate::ThreadCommunicate(QObject *parent) : QObject (parent)
{
    qRegisterMetaType<ThreadCommunicate::mydata>("ThreadCommunicate::mydata");
}

void ThreadCommunicate::senddata()
{
    int i = 0;
    while(i<100){
        QThread::sleep(1);
        i++;
        QString data = "线程通信样例" + QString::number(i);
        emit sendData(data);
    }
}

void ThreadCommunicate::senddata1()
{
    int i = 0;
    while(i<100)
    {
        QThread::sleep(1);
        i++;
        mydata md;
        md.info = "我爱写程序";
        md.flag = i;
        emit sendData1(md);
    }
}

main.cpp:

#include "client.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Client *w1 = new Client();
    w1->show();

    Client *w2 = new Client();
    w2->show();

    Client *w3 = new Client();
    w3->show();

    Client *w4 = new Client();
    w4->show();

    return a.exec();
}

client.ui:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Client</class>
 <widget class="QMainWindow" name="Client">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1057</width>
    <height>581</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Client</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <widget class="QGroupBox" name="groupBox">
    <property name="geometry">
     <rect>
      <x>30</x>
      <y>20</y>
      <width>501</width>
      <height>411</height>
     </rect>
    </property>
    <property name="title">
     <string>UDP通信</string>
    </property>
    <widget class="QTextEdit" name="textEdit_receive">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>80</y>
       <width>481</width>
       <height>191</height>
      </rect>
     </property>
    </widget>
    <widget class="QTextEdit" name="textEdit_send">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>280</y>
       <width>381</width>
       <height>111</height>
      </rect>
     </property>
    </widget>
    <widget class="QPushButton" name="pushButton_send">
     <property name="geometry">
      <rect>
       <x>410</x>
       <y>310</y>
       <width>80</width>
       <height>61</height>
      </rect>
     </property>
     <property name="text">
      <string>发送</string>
     </property>
    </widget>
    <widget class="QLineEdit" name="lineEdit">
     <property name="geometry">
      <rect>
       <x>10</x>
       <y>30</y>
       <width>151</width>
       <height>41</height>
      </rect>
     </property>
    </widget>
    <widget class="QPushButton" name="pushButton_init">
     <property name="geometry">
      <rect>
       <x>210</x>
       <y>27</y>
       <width>81</width>
       <height>41</height>
      </rect>
     </property>
     <property name="text">
      <string>初始化</string>
     </property>
    </widget>
   </widget>
   <widget class="QGroupBox" name="groupBox_2">
    <property name="geometry">
     <rect>
      <x>550</x>
      <y>20</y>
      <width>491</width>
      <height>411</height>
     </rect>
    </property>
    <property name="title">
     <string>线程通信</string>
    </property>
    <widget class="QTextEdit" name="textEdit_thread">
     <property name="geometry">
      <rect>
       <x>20</x>
       <y>40</y>
       <width>221</width>
       <height>271</height>
      </rect>
     </property>
    </widget>
    <widget class="QPushButton" name="pushButton_thread">
     <property name="geometry">
      <rect>
       <x>60</x>
       <y>340</y>
       <width>121</width>
       <height>51</height>
      </rect>
     </property>
     <property name="text">
      <string>qt内嵌数据开始</string>
     </property>
    </widget>
    <widget class="QPushButton" name="pushButton_thread_2">
     <property name="geometry">
      <rect>
       <x>310</x>
       <y>340</y>
       <width>121</width>
       <height>51</height>
      </rect>
     </property>
     <property name="text">
      <string>自定义数据开始</string>
     </property>
    </widget>
    <widget class="QTextEdit" name="textEdit_thread_2">
     <property name="geometry">
      <rect>
       <x>260</x>
       <y>40</y>
       <width>221</width>
       <height>271</height>
      </rect>
     </property>
    </widget>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1057</width>
     <height>19</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

Screenshot of the result:

 

 

Guess you like

Origin blog.csdn.net/wxy_csdn_world/article/details/104475069