1. 程式人生 > >QT訊號和槽的實現原理

QT訊號和槽的實現原理

訊號和槽是qt用於物件之間通訊的核心機制。其目的類似於當一個動作發生的時候,需要對這個動作做出相應的處理,類似的還有藉助於函式指標的回撥機制,通過回撥函式完成對此動作的操作。但是如果對一個龐雜的系統,這種回撥函式的維護是相當的麻煩和危險的,使用太多的回撥會導致高耦合的情況,這在實際開發過程中是儘量避免的。QT的訊號和槽機制避免了該問題,使用起來非常靈活。

使用訊號與槽,首先,類必須直接或間接繼承自QObject,在類入口處使用O_OBJECT巨集,這是必須的,因為必須是訊號槽機制由元物件系統(meta object system)提供。

訊號:signals或Q_SIGNALS宣告的函式,可以看作是一個請求或者一個動作的標誌。如果一個物件在達到一個狀態或者需要一個請求等操作的時候,其會觸發這個訊號。qt實現觸發請求,使用emit命令(emit 訊號函式)。

訊號通常是沒有返回值的,專案開發中一般都是void,函式中根據情況宣告對應的引數列表,該函式只需要宣告。

槽:slots或Q_SLOTS關鍵字宣告,槽函式其實就是一個普通的函式,槽函式裡邊的引數列表應該跟繫結的訊號函式引數列表(引數型別和個數)一致,當然引數個數可以比訊號少,多餘的訊號函式引數被忽略了,注意,引數槽函式引數個數少,但是前面的順序必須跟訊號函式一致。如:

signals:

void signalsTest(int A, int B);

private:

slots:

int slotsTest(int A));

int slotsTest(int B));  //該函式不能繫結signalsTest訊號。引數列表不一致

其訊號槽工作的過程是:先將訊號和槽函式進行繫結,當一個物件通過emit發射一個訊號的時候,則和其連線的物件的槽函式進行處理,等槽函式處理完成之後emit退出並執行接下來的內容。

查詢資料的時候發現有的把訊號槽機制當成觀察者模式來理解,開始感覺沒什麼問題,但是從關係的角度來說,觀察者模式通常對應的關係是1對多(n)的情況,即被觀察者(1)和觀察者(n)。我們可以把訊號當成被觀察者,槽函式當成觀察者,因為一個訊號可以對應多個槽函式,當訊號傳送時繫結的槽函式都會執行,執行順序不確定。不過訊號槽機制還有多個訊號對應一個槽函式的情況,以及一個訊號對一個訊號的情況。所以建議讀者在理解的過程中注意,如果當初觀察者模式時,不要只關注一個訊號對應多個槽函式的情況。

 

參考:

https://blog.csdn.net/iEearth/article/details/74025072