貼上兩篇博文
一、http://www.cnblogs.com/findumars/p/5031239.html
循序漸進介紹了,怎樣正確的讓槽函數工作在子線程中。
同時介紹了信號槽的綁定與線程的關系
QObject::connect
涉及信號槽,我們就躲不過 connect 函數,只是這個函數大家太熟悉。我不好意思再用一堆廢話來描述它,但不說又不行,那么折中一下,只看它的最后一個參數吧(為了簡單起見,只看它最常用的3個值)
class Thread:public QThread
{
Q_OBJECT
public:
Thread(QObject* parent=0):QThread(parent){}
public slots:
void slot() { ... }
signals:
void sig();
protected:
void run() { ...}
};
int main(int argc, char** argv)
{
...
Thread thread;
...
}
下面的列表,我們暫稱為定理二:
1、自動連接(Auto Connection)
這是默認設置
如果信號在接收者所依附的線程內發射,則等同於直接連接
如果發射信號的線程和接受者所依附的線程不同,則等同於隊列連接
也就是這說,只存在下面兩種情況
2、直接連接(Direct Connection)
當信號發射時,槽函數將直接被調用。
無論槽函數所屬對象在哪個線程,槽函數都在發射信號的線程內執行。
3、隊列連接(Queued Connection)
當控制權回到接受者所依附線程的事件循環時,槽函數被調用。
槽函數在接收者所依附線程執行。
定理二強調兩個概念:發送信號的線程 和 接收者所依附的線程。而 slot 函數屬於我們在main中創建的對象 thread,即thread依附於主線程
隊列連接告訴我們:槽函數在接受者所依附線程執行。即 slot 將在主線程執行
直接連接告訴我們:槽函數在發送信號的線程執行。信號在那個線程發送呢??不定!
自動連接告訴我們:二者不同,等同於隊列連接。即 slot 在主線程執行
太繞了?不是么(要徹底理解這幾句話,你可能需要看Qt meta-object系統和Qt event系統)
怎么辦呢?
如果上兩節看不懂,就記住下面的話吧(自己總結的,用詞上估計會不太准確)。
QThread 是用來管理線程的,它所依附的線程和它管理的線程並不是同一個東西
QThread 所依附的線程,就是執行 QThread t(0) 或 QThread * t=new QThread(0) 的線程。也就是咱們這兒的主線程
QThread 管理的線程,就是 run 啟動的線程。也就是次線程
因為QThread的對象依附在主線程中,所以他的slot函數會在主線程中執行,而不是次線程。除非:
QThread 對象依附到次線程中(通過movetoThread)
slot 和信號是直接連接,且信號在次線程中發射
但上兩種解決方法都不好,因為QThread不是這么用的(Bradley T. Hughes)
二、https://blog.csdn.net/TurboIan/article/details/71125314
在此需要注意一點,對象內定義的成員變量是屬於定義該對象的線程的,意思是Worker是在main()定義,那么Worker中定義的成員變量是屬於主線程的,在其他slot函數中使用是屬於跨線程使用。
假定:
對象Worker是在主線程1中創建,那么Worker中的成員變量也屬於主線程1
Worker的槽函數function1是在線程2中工作,那么槽函數function1中使用Worker的成員變量,運行程序時,就會報如下錯誤:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTcpSocket(0x5c7f68), parent's thread is QThread(0x5b7f28), current thread is QThread(0x4ff700)
1、錯誤的代碼:
在Worker的構造函數中對QTcpSocket進行實例化,
Worker::Worker(QObject *parent)
: QObject(parent)
{
tcp = new QTcpSocket;
}
在線程槽函數中使用
void Connect()
{
tcp->connectToHost("127.0.0.1", 110);
tcp->waitForConnected();
}
2、正確的代碼
Worker::Worker(QObject *parent)
: QObject(parent)
{
}
在線程槽函數中使用
void Connect()
{
tcp = new QTcpSocket;
tcp->connectToHost("127.0.0.1", 110);
tcp->waitForConnected();
}
這樣tcp 的實例化是在線程中實現的!
三、線程退出
https://blog.csdn.net/qq_40450386/article/details/84991041
四、其他資料