在上週老師說了項目須要學習qt後,就去找了個qt的教程,看了看,教程一上來就開始介紹qt的信號與槽,說這是qt中一個很重要的東西,而後就下一步了……,後面的代碼中也沒有特別感覺到這個的強大與獨特(應該是對編程的理解還不夠深的緣由),就上網找了找技術博客看,發現大部分文章都對菜鳥不太友好,不過最終仍是讓我找到了一篇讓新手也能透徹明白的文章 ,這裏記錄一下本身的收穫。編程
先讓咱們看看它的定義:安全
聽着很強,很高級。框架
簡單的用途就是函數
當一個特定的事件發生時,一個或幾個被指定的信號就被髮射,槽就是一個返回值爲void的函數,若是存在一個或幾個槽和該信號相鏈接,那在該信號被髮射後,這個(些)槽(函數)就會馬上被執行
理解卻是不難,不就是觸發了一個函數嗎?徹底感覺不到做爲一個框架的核心特性的強大。學習
要感覺它的強大仍是得從它的做用中體會(也許教程中的老師也是這麼想的,只是我沒體會到……)。spa
在圖形界面編程中,不少時候咱們但願一個可視對象發生某種變化時通知另外一個或幾個對象,再一個地說,咱們但願任 何一類的對象能和其餘對象進行通信。例如,某個數值顯示窗口負責顯示某個滾動條對象的當前數值,當滾動條對象的值發生變化時,咱們但願數值顯示窗口能收到 來自滾動條對象發送的「數值改變」的信號,從而改變本身的顯示數值。.net
這些在其餘圖形框架中能夠用回調實現,不過,相比於回調函數,信號和槽機制是類型安全的(沒搞太懂爲何安全),一個信號的簽名必須與它的接收槽的簽名相匹配,這樣編譯器就能夠幫助咱們檢查類型是否匹配。信號和槽是很寬鬆的聯繫在一 起的,一個發射信號的對象不用考慮哪一個槽會接收這個信號,接收信號的槽的所在對象也不知道要鏈接的信號是哪一個對象發射的。QT的信號和槽機制能夠保證若是 你把一個信號和一個槽鏈接起來後,槽會在正確的時間使用信號的參數而被調用,信號和槽可使用任何數量、類型的參數。
換一種說法,在使用信號與槽時你得先鏈接一下他們。下面是信號與槽的代碼實現指針
使用信號和槽的QT對象: class UseSignalClass { Q_OBJECT public: UseSignalClass (void) {} int value (void) const {return _value;} public slots: int setValue (int value) {_value = value;} // 定義槽 signals: void valueChanged (int); private: int _value; } void UseSignalClass::setValue( int value ) { if ( value != _value ) { _val = value; emit valueChanged(value); } } emit valueChanged(value);這行代碼是發射一個信號valueChanged。 要想使一個槽在一個信號被髮射後被執行,要顯示地進行鏈接: UseSignalClass a,b; connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int)));
而後當a改變時,b也會跟着變,而b的改變不會影響到a,由於b不會給a發信號。code
下面是信號與槽的使用中的一些注意事項:對象
一、信號和槽的機制是很是有效的,可是它不像「真正的」回調那樣快。信號和槽稍微有些慢,這是由於它們所提供的靈活性。但這種損失相對來講是比較小的。但要追求高效率的話,好比在實時系統中就要儘可能少用這種機制。
二、信號和槽機制與普通函數的調用同樣,若是使用不當的話,在程序執行時有可能造成死循環,因此,在定義槽函數時必定要注意避免間接造成無限循環,即在槽中再次發射所接收到的一樣的信號。
三、若是一個信號和多個槽相關聯的話,那當這個信號被髮射時,與之相關聯的槽的執行順序將是髓機的,且順序不能指定。
四、宏定義不能用在signal和slot的參數中。
五、構造函數不能用在signals和slots聲明區域內。
六、函數指針不能做爲信號或槽的參數。
七、信號和槽不能有缺省參數值。
八、信號和槽不能攜帶模板類參數。
九、嵌套的類不能位於信號和槽區域內,也不能有信號或者槽。
十、友元聲明不能位於信號和槽的聲明區域內。
學習是一個一步一步的過程,學的時候千萬不要太着急,應該剋制本身總想直接搞最後一步的想法,畢竟那樣學習曲線會太過陡峭,容易讓人失去信心,就像此次要不是知道回調,在看相關博客時,確定也是看的雲裏霧裏的。