搜索
Table_bottom

标签云
Table_bottom

分类
Table_bottom

声明
文章若未特別註明,皆採用 知识共享许可协议 請自覺遵守
Table_bottom

存档
Table_bottom

匆匆过客
30501
Table_bottom

功能
Table_bottom

Qt中鏈接信號和槽的方法

最近又在用Qt寫東西,順便翻了翻Qt的文檔,發現鏈接信號和槽的方法有不少,Qt5和C++11的組合也帶來了一些不小變化。

所以有此一篇文章,對其稍加總結。

继续阅读

自記初習Qt

百無聊賴,於是就拿出Qt Creator來學一下Qt(C++)。若有錯誤,還望指正。


Qt使用標準的C++,只是加入了預處理器(moc)以及一些宏。這就意味着可以使用任意的C++編譯器來編譯Qt程序。

文件

Qt圖形界面程序一般有三個文件,通常狀態下後綴名爲:.ui、.h、.cpp。

.ui文件是界面的設計文件,本質是xml文件。在構建時會依據其產生一些源文件以進行編譯。

.h文件是標準的c++頭文件,內部包含各類聲明等內容。需要特別注意的是,如果要使用Qt的信號/槽機制,需要在類聲明代碼塊首部分加入Q_OBJECT宏。

.cpp文件顯然是普通的C++程序源代碼。

從預設的組織結構看,Qt中的.h文件中僅僅寫聲明,定義在相應的.cpp文件中書寫。這點看起來比微軟的VS中那些亂七八糟的強許多。

然而打開進行編譯的臨時目錄,其中依據.ui文件自動生成的.h文件中卻包含了一些定義。不過這似乎是有意爲之,而且沒有直接暴露在編程者面前,也算是很不錯的做法。

信號/槽

相傳Qt最引以爲傲的就是它的“信號/槽”機制。該機制是一個解耦程度極高的組件通信方案,允許組件間在互不相知的狀態下進行通信。

如名稱所示,“信號”表示發送消息的部分,“槽”表示接收消息的部分。當一個信號發出時,其相關聯的槽會被立即(實際上仍有極其微小的延遲)調用。

信號或者槽連同它的參數類型表,一起被稱爲其“簽名”,意即其標識。Qt通過簽名類辨識信號或槽,也通過簽名來判斷一個信號是否能和槽相關聯。事實上,一個信號可和多個槽對應,一個槽也可和多個信號對應,甚至信號也可以引發另一個信號,這也就爲編程帶來了極大的靈活性。

爲了便於編程,Qt已對其組件(例如PushButton)定義好了一些信號(例如“按下”),編程時可直接使用。

信號

信號是一個不需要定義的函數。它應當在類中聲明,並在代碼中被引發。

聲明信號,只需在類聲明中寫入

signals:
    void 信號名( 參數類型表 );

除了聲明方法不同以及槽可以用於信號/槽機制通信外,槽的一切均和普通函數一致。

聲明槽,應當在類聲明中加入:

訪問方式 slots:
	返回值類型 槽名( 參數表 );

之後在相應的.cpp文件中定義即可。

其中訪問方式可爲public、protected、private中任一種,並會導致槽的作用域不同(和C++標準概念中一致)。

關聯信號和槽

關聯信號和槽的通常做法是

connect(發送者, SIGNAL(信號(參數類型表)), 接受者/*即槽所在*/, SLOT(槽(參數類型表)));

其中SIGNAL和SLOT均爲宏,其參數中實際上要寫的是信號或者槽的簽名。之前說過,我們可以將一個信號和另一個信號關聯起來,這只需將上面的槽換成信號即可。

其中信號的參數可以比槽的多,多餘的部分在槽被激活(調用)時會被忽略掉。

實際上,關聯信號與槽的方法還有一些變體,具體可參考我的這篇文章。

解除信號和槽的關聯

解除信號和槽的關聯需要用到disconnect函數,其使用方法和connect幾乎一致:

disconnect(發送者, SIGNAL(信號(參數類型表)), 接受者, SLOT(槽(參數類型表)));

實際上,該函數中除了發送者外,其餘部分均可以填“0”,表示“任意”。

手動發送信號

有時候Qt自帶的信號無法滿足我們的需求,這時候我們就需要知道如何手動發送自己定義的信號。

手動發送信號,只需要在想要發送信號的地方使用emit關鍵字發送你的信號:

emit 信號( 參數 );

實際上,emit是一個宏,並且其內容爲空。這也就意味着完全可以不使用emit來發送一個信號。但是個人推薦使用emit來明確標識這是一個信號。