QT信號槽connect的第五個參數


用過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對應的相同,所以主線程與槽函數的線程是相同的。

所以小伙伴按實際情況來使用吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM