關於Qt訊號與槽機制的傳遞方向性研究

2021-05-24 13:18:26 字數 2068 閱讀 6970

最近由於專案的需求,一直在研究qt。訊號與槽機制是qt的一大特色,該機制允許兩者間傳遞引數,依次來實現物件間的通訊。這個引數會分別存在於訊號的引數列表和槽函式的引數列表中。需要注意的是,若將槽函式繫結至訊號,槽函式的引數列表元素數目只能少於等於訊號的引數列表元素數目。而且順序和型別不能改變。至於缺少的引數應從訊號引數尾部開始缺少。

突然今天想起來乙個問題,如果乙個物件發出訊號,將內部的乙個成員變數(非簡單型別)作為引數向外傳送,槽函式就可以接收到這個物件,那麼槽函式是否可以完全操作這個物件呢?如果可以完全操作,那麼這個訊號與槽機制就是乙個雙向的通訊過程,即a可以觸發b,b又能對a進行操作;如果操作無效,則說明該機制是乙個單向的通訊過程,即a觸發b,b進行處理,但不能反向寫資料。

閒言少敘,讓例項說話

建立標頭檔案customclasses.h

**如下:

這裡定義了三個類tperson、tsender和treceiver。

tperson是乙個很簡單的類,包含了乙個私有成員_name,分別具有get和set方法。

tsender類中包含乙個私有的tperson例項_p,click()方法模擬按鈕單擊,當執行click()方法後會發出newname(tperson p)訊號。

treceiver類中包含乙個getnewname(tperson p)槽,用於接收來自tsender的newname(tperson p)訊號。

建立對應的customclasses.cpp

**如下:

該檔案是上述內容的實現,但值得注意的是,在voidtreceiver::getnewname(tperson p)的實現中,對p引數進行了操作,呼叫了setname方法。

主檔案main.cpp

**如下:

int main(int argc, char *argv)

該**例項化tsender類和treceiver類,並繫結newname訊號與getnewname槽。**很簡單,其他的就不再多做介紹了。

下面看執行結果:

我們來分析一下這個程式。在宣告了send例項和recv例項後,繫結了相關事件。首先檢視了一下當前send物件中的tperson類例項 _p的name屬性。第一行顯示的是初始的jack;然後

呼叫了send的click()方法,該方法放出了newname訊號,此時該訊號被recv的getnewname槽函式接收,該函式顯示了當前接收到物件的name值。然後呼叫了接收物件的setname方法,將name設定為「rose」。槽函式執行完畢後,**跳轉到觸發newname訊號的位置,即click()方法的「emit

this

->newname(

this

->_p); 」後面;最後再顯示一下send例項內部的_p例項name屬性。此時觀察到雖然在槽函式中重新設定了name屬性,但並沒有改變訊號發起方例項的屬性值(依舊是jack)。因此我們可以說,這種傳遞物件的訊號與槽機制是單向通訊的。傳遞方向是訊號發出方到訊號接收方。當然這個例子中只是傳遞的乙個物件,本人試驗了一下,如果將上述**進行小幅修改,將傳遞引數變為物件指標,則最終會影響到訊號傳送發的資料。如下圖所示:

也就是說,如果傳遞的是指標,則該機制是雙向通訊的,關鍵還是看如何去使用它們。我個人不推薦使用指標傳遞。因為乙個訊號可以繫結多個槽函式,若其中有乙個對資料進行了修改,則會影響後續的槽函式執行,此時的引數狀態未知,也不易於維護。當然了,什麼事也不是絕對的,特殊情況下除外。

另外補充兩點:

第一:上文中提到的「槽函式」這個詞並不貼切。因為該方法是不能包含返回值的。必須是void,因此稱之為「槽過程」比較貼切,但是已經廣泛認同了這個叫法了,所以就沒有深究。

第二:開始時為了圖省事,將tperson、tsender和treceiver三個類的定義和實現都放到了main.cpp中。結果無論如何也編譯不過去。提示「undefined reference vtable for class ...」, ...是這三個類的類名。後來查到資料得知在qt程式編譯時,遇到signal和slots定義的地方會呼叫moc工具對其進行轉換,轉換為標準c++**(signal和slots不是標準c++的關鍵字),而moc工具是只識別.h檔案的,因此還是老老實實用標準的c++類定義方法,別偷懶了吧:)

QT訊號與槽機制

qt訊號與槽 posted on 2010 04 08 15 37 feisky 訊號與槽作為qt的核心機制在qt程式設計中有著廣泛的應用,本文介紹了訊號與槽的一些基本概念 元物件工具以及在實際使用過程中應注意的一些問題。qt是乙個跨平台的c gui應用構架,它提供了豐富的視窗部件集,具有物件導向 ...

Qt 訊號與槽機制

下部分 來自於我自己新增了傳遞引數的部分 ifndef my object define my object include define my slots define my signals protected define my emit class myobject struct metaob...

Qt的訊號與槽機制

qt使用訊號與槽機制進行物件間的通訊。當某個物件的狀態發生變化時,該物件會觸發 乙個訊號。該訊號和另外一些物件的槽函式繫結,訊號的觸發將導致執行這些槽函式,這些 槽函式將處理第乙個物件狀態的變化,完成物件之間的通訊。a 訊號與槽的定義 a 乙個類的訊號函式應該滿足以下語法約束。1 函式返回值是voi...