看過了簡單的Hello, world! 之後,下面來看看Qt最引以為豪的信號槽機制!
所謂信號槽,簡單來說,就像是插銷一樣:一個插頭和一個插座。怎麼說呢?當某種事件發生之後,比如,點擊了一下鼠標,或者按了某個按鍵,這時,這個組件就會發出一個信號。就像是廣播一樣,如果有了事件,它就漫天發聲。這時,如果有一個槽,正好對應上這個信號,那麼,這個槽的函數就會執行,也就是回調。就像廣播發出了,如果你感興趣,那麼你就會對這個廣播有反應。干巴巴的解釋很無力,還是看代碼:
#include <QtGui/QApplication>
#include <QtGui/QPushButton>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QPushButton *button = new QPushButton("Quit");
QObject::connect(button, SIGNAL(clicked()), &a, SLOT(quit()));
button->show();
return a.exec();
}
這是在Qt Creator上面新建的文件,因為前面已經詳細的說明怎麼新建工程,所以這裡就不再贅述了。這個程序很簡單,只有一個按鈕,點擊之後程序退出。(順便說一句,Qt裡面的button被叫做QPushButton,真搞不明白為什麼一個簡單的button非得加上push呢?呵呵)
主要是看這一句:
QObject::connect(button, SIGNAL(clicked()), &a, SLOT(quit()));
QObject是所有類的根。Qt使用這個QObject實現了一個單根繼承的C++。它裡面有一個connect靜態函數,用於連接信號槽。
當一個按鈕被點擊時,它會發出一個clicked信號,意思是,向周圍的組件們聲明:我被點擊啦!當然,其它很多組件都懶得理他。如果對它感興趣,就告訴QObject說,你幫我盯著點,只要button發出clicked信號,你就告訴我——想了想之後,說,算了,你也別告訴我了,直接去執行我的某某某函數吧!就這樣,一個信號槽就形成了。具體來說呢,這個例子就是QApplication的實例a說,如果button發出了clicked信號,你就去執行我的quit函數。所以,當我們點擊button的時候,a的quit函數被調用,程序退出了。所以,在這裡,clicked()就是一個信號,而quit()就是槽,形象地說就是把這個信號插進這個槽裡面去。
Qt使用信號槽機制完成了事件監聽操作。這類似與Swing裡面的listener機制,只是要比這個listener簡單得多。以後我們會看到,這種信號槽的定義也異常的簡單。值得注意的是,這個信號槽機制僅僅是使用的QObject的connect函數,其他並沒有什麼耦合——也就是說,完全可以利用這種機制實現你自己的信號監聽!不過,這就需要使用qmake預處理一下了!
細心的你或許發現,在Qt Creator裡面,SIGNAL和SLOT竟然變顏色了!沒錯,Qt確實把它們當成了關鍵字!實際上,Qt正是利用它們擴展了C++語言,因此才需要使用qmake進行預處理,比便使普通的C++編譯器能夠順利編譯。另外,這裡的signal和Unix系統裡面的signal沒有任何的關系!哦哦,有一點關系,那就是名字是一樣的!
信號槽機制是Qt關鍵部分之一,以後我們還會再仔細的探討這個問題的。