日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

QT子线程与主线程的信号槽通信

發(fā)布時(shí)間:2023/11/30 c/c++ 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 QT子线程与主线程的信号槽通信 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? ? ? 最近用QT做一個(gè)服務(wù)器,眾所周知,QT的主線程必須保持暢通,才能刷新UI。所以,網(wǎng)絡(luò)通信端采用新開線程的方式。在涉及到使用子線程更新Ui上的控件時(shí)遇到了點(diǎn)兒麻煩。網(wǎng)上提供了很多同一線程不同類間采用信號(hào)槽通信的方式,但是并不完全適合線程間的信號(hào)槽通信,這主要體現(xiàn)在自定義消息的傳遞上。


首先我們看看一般的方式:


testthread.h 文件

[cpp]?view plaincopy print?
  • #ifndef?TESTTHREAD_H??
  • #define?TESTTHREAD_H??
  • ??
  • #include?<QThread>??
  • ??
  • #include?"msg.h"??
  • ??
  • class?TestThread?:?public?QThread??
  • {??
  • ????Q_OBJECT??
  • public:??
  • ????explicit?TestThread(QObject?*parent?=?0);??
  • ??
  • protected:??
  • ????void?run();??
  • ??
  • signals:??
  • ????void?TestSignal(int);??
  • ??
  • private:??
  • ????Msg?msg;??
  • };??
  • ??
  • #endif?//?TESTTHREAD_H??

  • testthread.cpp文件

    [cpp]?view plaincopy print?
  • #include?"testthread.h"??
  • ??
  • TestThread::TestThread(QObject?*parent)?:??
  • ????QThread(parent)??
  • {??
  • }??
  • ??
  • void?TestThread::run()??
  • {??
  • ????//觸發(fā)信號(hào)??
  • ????emit?TestSignal(123);??
  • }??


  • 自己定義的類繼承了QThread類,重寫run函數(shù),然后觸發(fā)TestSignal信號(hào)。

    mainwindow.h

    [cpp]?view plaincopy print?
  • #ifndef?MAINWINDOW_H??
  • #define?MAINWINDOW_H??
  • ??
  • #include?<QMainWindow>??
  • ??
  • #include?"testthread.h"??
  • ??
  • namespace?Ui?{??
  • class?MainWindow;??
  • }??
  • ??
  • class?MainWindow?:?public?QMainWindow??
  • {??
  • ????Q_OBJECT??
  • ??
  • public:??
  • ????explicit?MainWindow(QWidget?*parent?=?0);??
  • ????~MainWindow();??
  • ??
  • private?slots:??
  • ????void?DisplayMsg(int);??
  • ??
  • private:??
  • ????Ui::MainWindow?*ui;??
  • ????TestThread?*t;??
  • };??
  • ??
  • #endif?//?MAINWINDOW_H??

  • mainwindow.cpp

    [cpp]?view plaincopy print?
  • #include?"mainwindow.h"??
  • #include?"ui_mainwindow.h"??
  • ??
  • MainWindow::MainWindow(QWidget?*parent)?:??
  • ????QMainWindow(parent),??
  • ????ui(new?Ui::MainWindow)??
  • {??
  • ????ui->setupUi(this);??
  • ??
  • ????//進(jìn)行connect前必須實(shí)例化??
  • ????t?=?new?TestThread();?????
  • ??
  • ????connect(t,?SIGNAL(TestSignal(int)),?this,?SLOT(DisplayMsg(int)));??
  • ??
  • ????//執(zhí)行子線程??
  • ????t->start();???
  • }??
  • ??
  • void?MainWindow::DisplayMsg(int?a)??
  • {??
  • ????ui->textBrowser->append(QString::number(a));??
  • }??
  • ??
  • MainWindow::~MainWindow()??
  • {??
  • ????delete?ui;??
  • }??

  • Mainwindow里面連接信號(hào)槽,并且將收到的int參數(shù)顯示在界面上。


    運(yùn)行效果



    下面我們對(duì)程序進(jìn)行一些簡(jiǎn)單,修改,使得它傳輸我們的自定義消息。


    testthread.h 文件

    [cpp]?view plaincopy print?
  • #ifndef?TESTTHREAD_H??
  • #define?TESTTHREAD_H??
  • ??
  • #include?<QThread>??
  • ??
  • #include?"msg.h"??
  • ??
  • class?TestThread?:?public?QThread??
  • {??
  • ????Q_OBJECT??
  • public:??
  • ????explicit?TestThread(QObject?*parent?=?0);??
  • ????Msg?msg;??
  • ??
  • protected:??
  • ????void?run();??
  • ??
  • signals:??
  • ????void?TestSignal(Msg);???//Msg!!!??
  • };??
  • ??
  • #endif?//?TESTTHREAD_H??

  • testthread.h 文件

    [cpp]?view plaincopy print?
  • #include?"testthread.h"??
  • ??
  • TestThread::TestThread(QObject?*parent)?:??
  • ????QThread(parent)??
  • {??
  • }??
  • ??
  • void?TestThread::run()??
  • {??
  • ????msg.int_info?=?999;??
  • ????msg.str_info?=?"Hello?Main?Thread!";??
  • ????//觸發(fā)信號(hào)??
  • ????emit?TestSignal(msg);??
  • }??

  • mainwindow.h 文件

    [cpp]?view plaincopy print?
  • #ifndef?MAINWINDOW_H??
  • #define?MAINWINDOW_H??
  • ??
  • #include?<QMainWindow>??
  • ??
  • #include?"testthread.h"??
  • #include?"msg.h"??
  • ??
  • namespace?Ui?{??
  • class?MainWindow;??
  • }??
  • ??
  • class?MainWindow?:?public?QMainWindow??
  • {??
  • ????Q_OBJECT??
  • ??
  • public:??
  • ????explicit?MainWindow(QWidget?*parent?=?0);??
  • ????~MainWindow();??
  • ??
  • private?slots:??
  • ????void?DisplayMsg(Msg);???//Msg!!!??
  • ??
  • private:??
  • ????Ui::MainWindow?*ui;??
  • ????TestThread?*t;??
  • };??
  • ??
  • #endif?//?MAINWINDOW_H??

  • mainwindow.cpp 文件

    [cpp]?view plaincopy print?
  • #include?"mainwindow.h"??
  • #include?"ui_mainwindow.h"??
  • ??
  • MainWindow::MainWindow(QWidget?*parent)?:??
  • ????QMainWindow(parent),??
  • ????ui(new?Ui::MainWindow)??
  • {??
  • ????ui->setupUi(this);??
  • ??
  • ????//進(jìn)行connect前必須實(shí)例化??
  • ????t?=?new?TestThread();??
  • ??
  • ????//Msg!!!??
  • ????connect(t,?SIGNAL(TestSignal(Msg)),?this,?SLOT(DisplayMsg(Msg)));??
  • ??
  • ????//執(zhí)行子線程??
  • ????t->start();??
  • }??
  • ??
  • void?MainWindow::DisplayMsg(Msg?msg)??
  • {??
  • ????ui->textBrowser->append(QString::number(msg.int_info));??
  • ????ui->textBrowser->append(msg.str_info);??
  • }??
  • ??
  • MainWindow::~MainWindow()??
  • {??
  • ????delete?ui;??
  • }??

  • 此時(shí)再進(jìn)行編譯,能夠通過,但是Qt Creator會(huì)有提示

    [cpp]?view plaincopy print?
  • QObject::connect:?Cannot?queue?arguments?of?type?'Msg'??
  • (Make?sure?'Msg'?is?registered?using?qRegisterMetaType().)??

  • 并且運(yùn)行程序,不會(huì)有任何反應(yīng)。


    mainwindow.cpp文件 改動(dòng)為

    [cpp]?view plaincopy print?
  • ui->setupUi(this);??
  • ??
  • qRegisterMetaType<Msg>("Msg");??

  • 此時(shí)能夠正常運(yùn)行




    說明:

    在線程間使用信號(hào)槽進(jìn)行通信時(shí),需要注意必須使用元數(shù)據(jù)類型

    Qt內(nèi)生的元數(shù)據(jù)類型,如int double QString 等

    如果要用自己定義的數(shù)據(jù)類型,需要在connect前將其注冊(cè)為元數(shù)據(jù)類型。形式見代碼。

    總結(jié)

    以上是生活随笔為你收集整理的QT子线程与主线程的信号槽通信的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。