Qt之信號槽淺探

連接類型

AutoConnection (Qt::AutoConnection):根據對象所在的線程自動選擇合適的連接類型。如果信號發送者和接收者在同一線程中運行,則使用直接連接;否則使用隊列連接。
DirectConnection (Qt::DirectConnection):信號發送時,槽函數會在發送信號的線程中立即執行。適用于信號發送者和接收者在同一線程中運行的情況。

直接連接時,信號與槽之間的響應形式為同步的直接調用,調用流程如下:
emit signal-->QMetaObject::activate-->QSlotObjectBase::call-->receiver::slot

QueuedConnection (Qt::QueuedConnection):信號發送時,將槽函數調用封裝為一個事件并放入接收者所在線程的事件隊列中,槽函數會在接收者的線程中執行。適用于跨線程通信的情況。

隊列連接時,信號發送時,判斷類型為c->connectionType == Qt::QueuedConnection,構造一個MetaCall事件,通過 QCoreApplication::postEvent將事件加到事件隊列中在事件循環處理,調用流程如下:
emit signal-->QMetaObject::activate-->queued_activate ...事件循環...
QEventDispatcherWin32::sendPostedEvents-->QEvent::MetaCall-->receiver::slot

    QMetaCallEvent *ev = c->isSlotObject ?
        new QMetaCallEvent(c->slotObj, sender, signal, nargs, types, args) :
        new QMetaCallEvent(c->method_offset, c->method_relative, c->callFunction, sender, signal, nargs, types, args);
    QCoreApplication::postEvent(c->receiver, ev);

BlockingQueuedConnection (Qt::BlockingQueuedConnection):(慎用,sender和reciver處于同線程時會出現死鎖)類似于隊列連接,但發送信號的線程會阻塞,直到槽函數在接收者的線程中執行完成。常用于需要確保信號和槽按順序執行的情況。

Qt: Dead lock detected while activating a BlockingQueuedConnection: Sender is Sender(0x32ffe64), receiver is Worker(0x32ffe3c)

UniqueConnection (Qt::UniqueConnection):防止重復連接相同的信號和槽,使用UniqueConnection進行連接時,如果是已存在的連接則本次不會重復連接。

除了加UniqueConnection,否則同一reciver多次connect時都會被加入到列表中,在sender發送信號時被多次調用
QObject::connect(&mainWindow.sender, &Sender::signalToSend, &worker, &Worker::doWork);
QObject::connect(&mainWindow.sender, &Sender::signalToSend, &worker, &Worker::doWork);

recever被銷毀時,自動從sender的list = &connectionLists->at(signal_index);中移除。在QObject對象銷毀時,會把處于posted事件隊列中的事件全部刪除,所以QEvent::MetaCall在對象銷毀后也不會調用。

QObjectPrivate::~QObjectPrivate()
{
...
    if (postedEvents)
        QCoreApplication::removePostedEvents(q_ptr, 0);
...
}

那么,什么情況下會出現對象銷毀,又觸發信號
void QObjectPrivate::deleteChildren()

為啥對象在delete后,繼續發送關聯該對象槽函數的信號時,觸發的receiver是空的


image.png
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容