用過QT的小伙伴都知道連接信號槽的connect方法,但是這個方法有第五個參數,一般都是用的默認的
connect(th,SIGNAL(started()),tmpmyobject,SLOT(showID()));
今天給大家講講第五個參數的用法
一、基本概念:
1、Qt::AutoConnection: 默認值,使用這個值則連接類型會在信號發送時決定。如果接收者和發送者在同一個線程,則自動使用Qt::DirectConnection類型。如果接收者和發送者不在一個線程,則自動使用Qt::QueuedConnection類型。
2、Qt::DirectConnection:槽函數會在信號發送的時候直接被調用,槽函數運行於信號發送者所在線程。效果看上去就像是直接在信號發送位置調用了槽函數。這個在多線程環境下比較危險,可能會造成奔潰。
3、Qt::QueuedConnection:槽函數在控制回到接收者所在線程的事件循環時被調用,槽函數運行於信號接收者所在線程。發送信號之后,槽函數不會立刻被調用,等到接收者的當前函數執行完,進入事件循環之后,槽函數才會被調用。多線程環境下一般用這個。
4、Qt::BlockingQueuedConnection:槽函數的調用時機與Qt::QueuedConnection一致,不過發送完信號后發送者所在線程會阻塞,直到槽函數運行完。接收者和發送者絕對不能在一個線程,否則程序會死鎖。在多線程間需要同步的場合可能需要這個。
5、Qt::UniqueConnection:這個flag可以通過按位或(|)與以上四個結合在一起使用。當這個flag設置時,當某個信號和槽已經連接時,再進行重復的連接就會失敗。也就是避免了重復連接。
二、具體實例
1 #include "MyObject.h" 2 #include 3 #include 4 #include 5 6 int main(int argc, char *argv[]) 7 { 8 QApplication a(argc, argv); 9 10 qDebug() << QString("main thread id:") << QThread::currentThreadId(); 11 12 MyObject object; 13 QThread thread; 14 object.moveToThread(&thread); 15 QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start())); 16 thread.start(); 17 18 return a.exec(); 19 }
"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; 2 QThread thread; 3 //object.moveToThread(&thread); 4 QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()), Qt::DirectConnection); 5 thread.start();
"main thread id:" 0x2688
"my object thread id:" 0x2110
顯然主線程與槽函數的線程是不同的,MyObject所依附的線程為主線程(因為注釋掉了moveToThread),繼上面介紹的Qt::DirectConnection(無論槽函數所屬對象在哪個線程,槽函數都在發射信號的線程內執行)。也就是說started()信號發射是在次線程中進行的,槽函數也是在次線程中進行的,所以主線程與槽函數的線程是不同的。
1 MyObject object; 2 QThread thread; 3 //object.moveToThread(&thread); 4 QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()), Qt::QueuedConnection); 5 thread.start();
查看運行結果:
"main thread id:" 0x24ec
"my object thread id:" 0x24ec
顯然主線程與槽函數的線程是相同的,繼上面介紹的Qt::QueuedConnection(槽函數在接收者所依附線程執行)。也就是說started()信號發射是在次線程中進行的,但MyObject所依附的線程為主線程(因為注釋掉了moveToThread),所以主線程與槽函數的線程必然是相同的。
1 MyObject object; 2 QThread thread; 3 //object.moveToThread(&thread); 4 QObject::connect(&thread, SIGNAL(started()), &object, SLOT(start()), Qt::AutoConnection); 5 thread.start();
"main thread id:" 0x2700
"my object thread id:" 0x2700
顯然主線程與槽函數的線程是相同的,MyObject所依附的線程為主線程(因為注釋掉了moveToThread),繼上面介紹的Qt::AutoConnection(如果信號在接收者所依附的線程內發射,則等同於直接連接。如果發射信號的線程和接受者所依附的線程不同,則等同於隊列連接。)。因為started()信號和MyObject依附的線程不同,所以結果和Qt::QueuedConnection對應的相同,所以主線程與槽函數的線程是相同的。
所以小伙伴按實際情況來使用吧。