Qt::AutoConnection
自動連接:(默認值)如果信號在接收者所依附的線程內發射,則等同於直接連接。如果發射信號的線程和接受者所依附的線程不同,則等同於隊列連接。
Qt::DirectConnection
直接連接:當信號發射時,槽函數將直接被調用。無論槽函數所屬對象在哪個線程,槽函數都在發射信號的線程內執行。
Qt::QueuedConnection
隊列連接:當控制權回到接受者所依附線程的事件循環時,槽函數被調用。槽函數在接收者所依附線程執行。也就是說:這種方式既可以在線程內傳遞消息,也可以跨線程傳遞消息
Qt::BlockingQueuedConnection
與Qt::QueuedConnection類似,但是會阻塞等到關聯的slot都被執行。這里出現了阻塞這個詞,說明它是專門用來多線程間傳遞消息的。
MyObject.h
#ifndef MYOBJECT_H #define MYOBJECT_H #include class MyObject : public QObject { Q_OBJECT public: explicit MyObject(QObject *parent = 0); public slots: void start(); }; #endif // MYOBJECT_H
MyObject.cpp
#include "MyObject.h" #include #include MyObject::MyObject(QObject *parent) : QObject(parent) { } void MyObject::start() { qDebug() << QString("my object thread id:") << QThread::currentThreadId(); }
main.cpp
#include "MyObject.h" #include #include #include int main(int argc, char *argv[]) { QApplication a(argc, argv); qDebug() << QString("main thread id:") << QThread::currentThreadId(); MyObject object; QThread thread; object.moveToThread(&thread); QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start())); thread.start(); return a.exec(); }
"main thread id:" 0xf08
"my object thread id:" 0x216c
顯然主線程與槽函數的線程是不同的(你可以多次嘗試,屢試不爽。。。),因為moveToThread后MyObject所在的線程為QThread,繼上面介紹的thread.start()執行后首先會發射started()信號,也就是說started()信號發射是在次線程中進行的,所以無論采取Qt::AutoConnection、Qt::DirectConnection、Qt::QueuedConnection哪種連接方式,主線程與槽函數的線程都是不同的。
1、修改代碼如下:
MyObject object; QThread thread; //object.moveToThread(&thread); QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()), Qt::DirectConnection); thread.start();
"main thread id:" 0x2688
"my object thread id:" 0x2110
顯然主線程與槽函數的線程是不同的,MyObject所依附的線程為主線程(因為注釋掉了moveToThread),繼上面介紹的Qt::DirectConnection(無論槽函數所屬對象在哪個線程,槽函數都在發射信號的線程內執行)。也就是說started()信號發射是在次線程中進行的,槽函數也是在次線程中進行的,所以主線程與槽函數的線程是不同的。
2、修改代碼如下:
MyObject object; QThread thread; //object.moveToThread(&thread); QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()), Qt::QueuedConnection); thread.start();
查看運行結果:
"main thread id:" 0x24ec
"my object thread id:" 0x24ec
顯然主線程與槽函數的線程是相同的,繼上面介紹的Qt::QueuedConnection(槽函數在接收者所依附線程執行)。也就是說started()信號發射是在次線程中進行的,但MyObject所依附的線程為主線程(因為注釋掉了moveToThread),所以主線程與槽函數的線程必然是相同的。
3、修改代碼如下:
MyObject object; QThread thread; //object.moveToThread(&thread); QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()), Qt::AutoConnection); thread.start();
"main thread id:" 0x2700
"my object thread id:" 0x2700
顯然主線程與槽函數的線程是相同的,MyObject所依附的線程為主線程(因為注釋掉了moveToThread),繼上面介紹的Qt::AutoConnection(如果信號在接收者所依附的線程內發射,則等同於直接連接。如果發射信號的線程和接受者所依附的線程不同,則等同於隊列連接。)。因為started()信號和MyObject依附的線程不同,所以結果和Qt::QueuedConnection對應的相同,所以主線程與槽函數的線程是相同的。