標籤:idg 回調 技術 編譯 c++ IV private 對象 一起
針對訊號和槽的專題研究
引言:訊號(signal)和槽(slot)用於對象間的通訊。訊號/槽機制是Qt的一個重要特徵。 在圖形化使用者介面編程中,常需要將一個視窗組件的變化通知給另一個視窗組件,或者說希望對象間進行通訊。一般的圖形化使用者介面編程中採用回呼函數進行對象間通訊,這樣回調和處理函數捆綁在一起,沒有signal和slot機制的簡便和靈活。
內容介紹:Qt的視窗組件有很多預定義的訊號,slot是一個可以被調用處理特定訊號的函數。Qt的視窗組件又很多預定義的槽,當一個特定事件發生的時候,一個訊號被發射,對訊號感興趣的slot就會調用對應響應函數。訊號/槽機制在QObject類中實現,從QObject類或者它的一個子類(比如QWidget類)繼承的所有類可以包含訊號和槽。當對象改變它們的狀態的時候,訊號被發送,對象不關心有沒有其它對象接收到它所發射的訊號。槽是類的正常成員函數。可以將訊號和槽通過connect函數任意相連。當一個訊號被發射它所串連的槽會被立即執行,就像一個普通函數調用一樣。
一個帶有訊號和槽的Qt類Foo聲明如下:
class Foo : public QObject
{
Q_OBJECT //包含訊號和/或者槽的類必須聲明Q_OBJECT
public:
Foo();
int value() const { return val; }
public slots:
void setValue( int ); //槽的聲明
signals:
void valueChanged( int ); //訊號聲明
private:
int val;
};
void Foo::setValue( int v )
{
if ( v != val ) {
val = v;
emit valueChanged(v); //發送訊號
}
}
下面把兩個對象串連在一起:
Foo a, b;
connect(&a, SIGNAL(valueChanged(int)), &b, SLOT(setValue(int)));//訊號與槽串連
b.setValue( 11 ); // a == undefined b == 11
a.setValue( 79 ); // a == 79 b == 79
b.value();
調用a.setValue(79)會使a發射一個valueChanged() 訊號,b將會在它的setValue()槽中接收這個訊號,也就是b.setValue(79) 被調用。接下來b會發射同樣的valueChanged()訊號,但是因為沒有槽被串連到b的valueChanged()訊號,所以沒有發生任何事(訊號消失了)。
signals、slots和emit不是C++的標準關鍵字,需要預先處理程式改變或者移去了signals、slots和emit 這些關鍵字,然後再使用標準的C++編譯器。對包含有訊號和槽的類定義運行MOC(Meta Object Compiler)。產生一個可以和其它對象檔案編譯和串連成引用程式的C++源檔案。
槽是普通成員函數,它和普通成員函數一樣分為public、protected和private三類,public slots表示聲明的是任何訊號都可以相連的槽。protected slots表示這個類的槽和它的子類的訊號才能串連。private slots表示這個類本身的訊號可以串連這個類的槽。
《Windows編程》微型技術報告二