Qt文档阅读笔记-Qt工作笔记-QThread解析与实例(主线程发送信号给子线程)
目錄
QThread
官方解析
博主栗子
子線程發射信號給主線程
QThread
官方解析
Detailed Description
QThread類提供了跨平臺的線程管理的API。
QThread對象在程序中管理一個線程。 使用run()來執行,默認情況下run()通過調用exec()實現事件循環,并且run()使得QThread的對象的線程中Qt的事件循環跑起來。
可以用QObject::moveToThread()使worker對象放入線程中。
在這個代碼里面Worker的槽函數在另外一個線程中執行。但可以使用信號與槽讓任意的object對象(繼承了QObject,并且帶有Q_OBJECT宏)信號連接Worker的槽函數。這種跨線程的信號與槽的連接方式是安全的,這得歸功于connect()函數的第五個參數(參考鏈接)默認調用了queued connections。
另外一種方式讓代碼運行在其他線程的方式是,子類化QThread類,并且重新實現run()函數,栗子如下:
在這個栗子中,thread將會在函數返回的時候退出。他們將不會在線程中運算事件循環,除非他們調用exec().
要注意QThread實例存在與誰實例化他的線程中,而不是在誰調用了run()這個函數的線程中。這就意味著QThread以隊列連接的信號與槽,將會執行在實例化他的線程中,而不是調用run()函數這個線程中。因此如果希望在新線程里面調用槽函數得使用worker對象顯示出的方式;不應該將槽函數直接實例在子類化的QThread中。
當子類化QThread類后,構造函數會舊的(實例化他的)那個線程中執行,而run()的執行將會在新線程中。如果這兩個函數都訪問了成員變量,從兩個不同的線程中訪問這個變量,要檢測這么做是否安全!
Note:要小心,在不同對象或者線程中交互。查看Synchronizing Threads查看詳情!
?
博主栗子
子線程發射信號給主線程
當子線程里面emit一個signal給主線程,這是十分常見的,但主線程emit一個signal給子線程那么會發送些什么呢!
運行截圖如下:
源碼瑞星啊:
widget.h
#ifndef WIDGET_H #define WIDGET_H#include <QWidget>class QThread; class Worker;class Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent = 0);~Widget();protected:void timerEvent(QTimerEvent *event)Q_DECL_OVERRIDE;signals:void hello();void sendMsg();private:QThread *thread[3];Worker *worker[3]; };#endif // WIDGET_Hworker.h
#ifndef WORKER_H #define WORKER_H#include <QObject>class Worker : public QObject {Q_OBJECT public:Worker(QObject *parent = 0);public slots:void beginToWork();void mainThreadMsg(); };#endif // WORKER_Hmain.cpp
#include "widget.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); }widget.cpp
#include "widget.h" #include "worker.h" #include <QDebug> #include <QThread> Widget::Widget(QWidget *parent): QWidget(parent) {for(int i=0;i<3;i++){thread[i]=new QThread;worker[i]=new Worker;worker[i]->moveToThread(thread[i]);connect(thread[i],&QThread::finished,worker[i],&QObject::deleteLater);connect(this,&Widget::hello,worker[i],&Worker::beginToWork);connect(this,SIGNAL(sendMsg()),worker[i],SLOT(mainThreadMsg()),Qt::DirectConnection);thread[i]->start();}emit hello();startTimer(1000);}Widget::~Widget() {for(int i=0;i<3;i++){thread[i]->quit();thread[i]->wait();delete thread[i];delete worker[i];} }void Widget::timerEvent(QTimerEvent *event) {Q_UNUSED(event)emit sendMsg();// for(int i=0;i<3;i++){ // qDebug()<<"main thread, worker "<<i; // worker[i]->mainThreadMsg(); // } }worker.cpp
#include "worker.h" #include <QDebug> #include <QThread>Worker::Worker(QObject *parent) : QObject(parent) {}void Worker::beginToWork() {while(true){QThread::sleep(2);qDebug()<<QThread::currentThreadId()<<" beginToWork";mainThreadMsg();} }void Worker::mainThreadMsg() {qDebug()<<"mainThreadMsg called!"<<QThread::currentThreadId(); }?
總結
以上是生活随笔為你收集整理的Qt文档阅读笔记-Qt工作笔记-QThread解析与实例(主线程发送信号给子线程)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Qt工作笔记-Qt文档阅读笔记-qual
- 下一篇: Qt文档阅读笔记-QThreadPool