QT中信號和槽淺淺淡淡
所有從 QObject 或其子類 ( 例如 Qwidget) 派生的類都能夠包含信號和槽。當對象改變其狀態(tài)時,信號就由該對象發(fā)射 (emit) 出去,這就是對象所要做的全部事情,它不知道另一端是誰在接收這個信號。這就是真正的信息封裝,它確保對象被當作一個真正的軟件組件來使用。槽用于接收信號,但它們是普通的對象成員函數(shù)。一個槽并不知道是否有任何信號與自己相連接。而且,對象并不了解具體的通信機制。
使用自定義的信號和槽,需要注意以下幾點:
1、類的聲明和實現(xiàn)分別放在.h和.cpp文件中;
2、類聲明中包含Q_OBJECT宏;
3、信號只要聲明不要設(shè)計其的實現(xiàn)函數(shù);
4、發(fā)射信號用emit關(guān)鍵字;
5、自定義槽的實現(xiàn)與普通成員函數(shù)的實現(xiàn)一樣。
當程序中所使用的類中具有用戶自定義的槽和信號時,你需要使用moc(元對象編譯器)對程序進行編譯。
編譯方法一:
你可以將moc文件編譯為目標文件,之后把它與ClassDefinion.cpp和main.cpp一起鏈接,下面具體的操作步驟:
- #moc ClassDeclaration.h -o ClassDeclaration.cpp
- #g++ -c ClassDeclaration.cpp -o ClassDeclaration.o
- #g++ -c ClassDefinion.cpp -o ClassDefinion.o
- #g++ -c main.cpp -o main.o
- #g++ -lqt ClassDefinion.o ClassDeclaration.o main.o -o MyProgram
編譯方法二:
創(chuàng)建一個空的文件夾,把源文件ClassDeclaration.h,ClassDefinion.cpp和main.cpp放入其中,執(zhí)行以下命令:
- #qmake -project
- #qmake
- #make
完成上述步驟后,就生成可執(zhí)行文件了(可執(zhí)行文件的名與你所創(chuàng)建的文件夾的名稱相同),我們就可以運行它了。
創(chuàng)建用戶自定義的信號與槽的具體步驟:
首先你需要在類聲明中聲明自定義的信號和槽。在關(guān)鍵字public slots:下聲明自定義槽;在signals:關(guān)鍵字下聲明自定義的信號。如下例所示:
- class MyMainWindow : public QWidget
- {
- Q_OBJECT
- public:
- void MyMainWindow();
- void SetValue(int);
- signals:
- void ValueChanged(int);
- public slots:
- void ChangeValue(int);
- };
正如你可能猜想到的,只有當一個新的值傳遞給SetValue()函數(shù)時,SetValue()函數(shù)才應(yīng)該調(diào)用ValueChanged()信號。之后,通過將ValueChanged()信號連接到ChangeValue()槽,使得當有新值傳遞給SetValue()函數(shù)時,能夠引起數(shù)值的變化。多數(shù)情況下,這是不必要的,但它演示了信號的使用方法。SetValue()函數(shù)可以像下面格式實現(xiàn):
- void MyMainWindow::SetValue(int value)
- {
- if(value!=oldvalue)
- {
- oldvalue=value;
- emit ValueChanged(value);
- }
- }
如你看到的只有,當新值與舊值不同時才發(fā)射ValueChanged()信號,且oldvalue將被修改為value。應(yīng)注意的是,信號與槽一類的普通函數(shù)不同,它只能使用emit關(guān)鍵字發(fā)射。ChangeValue()可定義為:
- void MyMainWindow::ChangeValue(int value)
- {
- FunctionForChangingTheValue(value);
- }
在這段代碼中,調(diào)用 FunctionForChangingTheValue( )函數(shù)去修改數(shù)據(jù)。你需要做的***一件事是將信號和槽連接起來:
- connect(this,SIGNAL(ValueChanged(int)),this,SLOT(ChangeValue(int)));
這個例子的功能是當調(diào)用SetValue()函數(shù)時,檢查新值是否等于舊值。如果不等,則發(fā)射ValueChanged()信號,又因為 ValueChanged()信號被連接到ChangeValue槽,因此當發(fā)射ValueChanged()信號時將執(zhí)行ChangeValue() 槽。之后,ChangeValue()槽調(diào)用FunctionForChangingTheValue()函數(shù)去修改實際數(shù)據(jù)。