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