Qt的信號與槽(二)
- 1.自定義槽
- 2.通過圖形化界面來生成自定義槽
- 3.自定義信號
- 3.信號和槽帶參數
- 4.參數數量
- 5.connect函數的設計
🌟hello,各位讀者大大們你們好呀🌟🌟
🚀🚀系列專欄:【Qt的學習】
📝📝本篇內容:自定義槽;通過圖形化界面來生成自定義槽;自定義信號;信號和槽帶參數;參數數量;connect函數的設計
????上一篇:Qt的信號與槽(一)
💖💖作者簡介:軒情吖,請多多指教(>> ????? ) ??-
1.自定義槽
在Qt中我們也可以自己定義信號和槽,我們先來講自定義槽,其實自定義的槽和普通的成員函數沒有區別。不過在以前的版本中我們對于自定義的槽函數聲明時需要放在public/private/protected slots:中,
學習C++后的同學應該都知道,這個public slots不是C++標準,這是Qt自己拓展的關鍵字,Qt通過qmake代碼生成代碼的方式,掃描到有slots這種,基于特定的關鍵字生成一堆代碼(元編程)。
這是最簡單的自定義槽,前面也見過
2.通過圖形化界面來生成自定義槽
這個窗口列出了QPushButton提供的所有信號和它父類的信號
經過我們一系列的操作,在.h和.cpp中,Qt都幫我們自動生成了槽函數的聲明和定義
功能也是沒有問題的
這其實是通過函數名的方式來自動連接信號和槽的
當函數名符合上面的規則后,Qt就自動能夠把信號和槽建立聯系
為了進行驗證,我們修改函數的名字
通過下面的提示我可以發現,調用QMetaObject::connectSlotsByName::這個函數就會觸發上述自動連接信號槽的規則。它其實不在我們可以直接看到的文件中,而是在Qt自動生成的ui_widget.h文件中調用的
如果使用圖像化界面來創建控件,就推薦使用這種方式來快速的鏈接信號和槽
如果是使用代碼的方式來創建控件,還是得通過connect來連接信號和槽,因為代碼中并沒有調用connectSlotsByName
3.自定義信號
在Qt開發中,自定義信號其實是比較少見的,主要還是自定義槽,因為自定義槽是為了當用戶觸發某些操作后,自定義槽函數是處理業務邏輯的。而自定義信號就是對應用戶的某一個操作,在GUI開發中,這些操作是可以窮舉的,因此我們的Qt內置的一些信號已經足夠我們使用了
在我們前面的使用也發現了,我們的信號本質上也就是一個函數,但是信號是一類比較特殊的函數:我們只需要寫出信號函數的聲明,并且告知Qt這是一個信號即可,信號函數的定義是在編譯階段Qt自動生成的。這主要是因為信號是Qt中特殊的機制,我們的信號函數的實現要配合Qt框架做很多既定的操作
并且我們的信號函數沒有返回值,是void類型的,但是有沒有參數都可以,也支持函數重載
對于自定義信號,Qt還提供了一個拓展的關鍵字signals,它像public/private一樣使用,用來聲明以下的函數是信號函數。它的作用是當qmake在調用代碼掃描/分析工具的時候,掃描到類中用signals這個關鍵字,就自動認為這個關鍵字聲明下的函數是信號函數,并且為信號函數自動生成函數定義
代碼實現目標:通過點擊按鈕來觸發自定義信號,自定義信號被觸發后,修改窗口標題
不知道大家有沒有注意是怎么觸發自定義信號的呢?Qt內置的信號觸發是不需要擔心的,Qt已經內置在框架里了,當用戶進行操作后,就會自動觸發。但是自定義信號需要手動觸發,就需要使用到emit關鍵字,這個單詞的意思是“發射”的意思,就是用來觸發自定義信號的。其實在現在的Qt5中不寫emit也是可以的,emit的功能都實現在自定義函數定義中了,現在的emit什么都干,但是為了代碼的可讀性,還是建議加上。
3.信號和槽帶參數
我們的信號和槽函數其實也可以帶函數參數的,當信號有信息需要傳遞給槽函數時,就可以通過參數進行傳遞了。因此我們的槽函數和信號的參數需要一致,但是這里有個例外,參數類型是需要一致,但是個數不一定需要一致,當不一致的時候,只需要滿足信號的參數個數必須多于槽函數即可。
先來看一段單純有相同數量參數的代碼
上面一整套代碼展示了通過傳遞參數可以起到一個復用代碼的作用,整體邏輯一致,但是數據不同,就可以根據不同場景傳遞不同參數
Qt內置的信號也有帶參數的,只是不需要我們進行傳遞
4.參數數量
接下來該談談我們參數數量的問題了?為什么Qt允許信號的參數多于槽函數而不是一一對應呢?
這其實也是為了更加的靈活,一個槽函數可能綁定多個信號。如果嚴格按照參數數量一致,就會導致信號綁定槽的要求變高。當參數個數不一致時,槽函數參數就會按照順序,拿到信號的的前N個參數,保證每個槽函數的參數都能拿到值。
當槽函數的參數多于信號的參數時就會報錯
但是當槽函數的參數少于信號的參數時,同樣的代碼就沒問題
并且我們在某個類中使用信號和槽的時候,一定不能沒有Q_OBJECT這個宏定義,必須在類的最開始的地方寫上
它會展開很多的代碼,并且這些代碼中也是宏,還會展開很多復雜的代碼,設計到Qt的設計原理,如果沒有這個宏,就會報錯,并且提醒你
5.connect函數的設計
其實說到底,我們的信號和槽的工作就是為了處理用戶想要執行的操作,所以說引入的connect函數,但是這只是在Qt中是這樣設計的。在像網頁開發,其他的語言中,是將槽函數是作為控件的一個屬性的,而不是像Qt那么麻煩。Qt那么設計的原因是為了能夠將控件和槽函數進行解耦,并且能夠支持多對多,即一個信號可以connect多個槽函數,一個槽函數可以connect多個信號。但是理想是美好的,現實是殘酷的,在實際的開發中,基本上用不到多對多,大部分都是一對一的情況。
上面演示了簡單的多對多使用
🌸🌸Qt的信號與槽(二)大概就講到這里啦,博主后續會繼續更新更多Qt的相關知識,干貨滿滿,如果覺得博主寫的還不錯的話,希望各位小伙伴不要吝嗇手中的三連哦!如有小伙伴需要Qt的安裝包可以私信我,你們的支持是博主堅持創作的動力!💪💪