Qt圖形編程基礎(chǔ)之:Qt/Embedded開(kāi)發(fā)入門(mén)
2.信號(hào)與插槽實(shí)現(xiàn)實(shí)例
(1)信號(hào)。
當(dāng)某個(gè)信號(hào)對(duì)其客戶或所有者內(nèi)部狀態(tài)發(fā)生改變時(shí),信號(hào)就被一個(gè)對(duì)象發(fā)射。只有定義了這個(gè)信號(hào)的類(lèi)及其派生類(lèi)才能夠發(fā)射這個(gè)信號(hào)。當(dāng)一個(gè)信號(hào)被發(fā)射時(shí),與其相關(guān)聯(lián)的插槽將被立刻執(zhí)行,就像一個(gè)正常的函數(shù)調(diào)用一樣。信號(hào)-插槽機(jī)制完全獨(dú)立于任何GUI事件循環(huán)。只有當(dāng)所有的槽返回以后發(fā)射函數(shù)(emit)才返回。如果存在多個(gè)槽與某個(gè)信號(hào)相關(guān)聯(lián),那么,當(dāng)這個(gè)信號(hào)被發(fā)射時(shí),這些槽將會(huì)一個(gè)接一個(gè)地執(zhí)行,但是它們執(zhí)行的順序?qū)?huì)是隨機(jī)的、不確定的,用戶不能人為地指定哪個(gè)先執(zhí)行、哪個(gè)后執(zhí)行。
Qt的signals關(guān)鍵字指出進(jìn)入了信號(hào)聲明區(qū),隨后即可聲明自己的信號(hào)。例如,下面定義了3個(gè)信號(hào):
signals:
voidmySignal();
voidmySignal(intx);
voidmySignalParam(intx,inty);
在上面的定義中,signals是Qt的關(guān)鍵字,而非C/C++的。接下來(lái)的一行voidmySignal()定義了信號(hào)mySignal,這個(gè)信號(hào)沒(méi)有攜帶參數(shù);接下來(lái)的一行voidmySignal(intx)定義了重名信號(hào)mySignal,但是它攜帶一個(gè)整形參數(shù),這有點(diǎn)類(lèi)似于C++中的虛函數(shù)。從形式上講信號(hào)的聲明與普通的C++函數(shù)是一樣的,但是信號(hào)卻沒(méi)有函數(shù)體定義。另外,信號(hào)的返回類(lèi)型都是void。信號(hào)由moc自動(dòng)產(chǎn)生,它們不應(yīng)該在.cpp文件中實(shí)現(xiàn)。
(2)插槽。
插槽是普通的C++成員函數(shù),可以被正常調(diào)用,它們惟一的特殊性就是很多信號(hào)可以與其相關(guān)聯(lián)。當(dāng)與其關(guān)聯(lián)的信號(hào)被發(fā)射時(shí),這個(gè)插槽就會(huì)被調(diào)用。插槽可以有參數(shù),但插槽的參數(shù)不能有缺省值。
插槽是普通的成員函數(shù),因此與其他的函數(shù)一樣,它們也有存取權(quán)限。插槽的存取權(quán)限決定了誰(shuí)能夠與其相關(guān)聯(lián)。同普通的C++成員函數(shù)一樣,插槽函數(shù)也分為3種類(lèi)型,即publicslots、privateslots和protectedslots。
n publicslots:在這個(gè)區(qū)內(nèi)聲明的槽意味著任何對(duì)象都可將信號(hào)與之相連接。這對(duì)于組件編程非常有用,用戶可以創(chuàng)建彼此互不了解的對(duì)象,將它們的信號(hào)與槽進(jìn)行連接以便信息能夠正確地傳遞。
n protectedslots:在這個(gè)區(qū)內(nèi)聲明的槽意味著當(dāng)前類(lèi)及其子類(lèi)可以將信號(hào)與之相連接。這適用于那些槽,它們是類(lèi)實(shí)現(xiàn)的一部分,但是其界面接口卻面向外部。
n privateslots:在這個(gè)區(qū)內(nèi)聲明的槽意味著只有類(lèi)自己可以將信號(hào)與之相連接。這適用于聯(lián)系非常緊密的類(lèi)。
插槽也能夠被聲明為虛函數(shù),這也是非常有用的。插槽的聲明也是在頭文件中進(jìn)行的。例如,下面聲明了3個(gè)插槽:
publicslots:
voidmySlot();
voidmySlot(intx);
voidmySignalParam(intx,inty);
(3)信號(hào)與插槽關(guān)聯(lián)。
通過(guò)調(diào)用QObject對(duì)象的connect()函數(shù)可以將某個(gè)對(duì)象的信號(hào)與另外一個(gè)對(duì)象的插槽函數(shù)或信號(hào)相關(guān)聯(lián),當(dāng)發(fā)射者發(fā)射信號(hào)時(shí),接收者的槽函數(shù)或信號(hào)將被調(diào)用。
該函數(shù)的定義如下所示:
boolQObject::connect(constQObject*sender,constchar*signal,constQObject*receiver,constchar*member)[static]
這個(gè)函數(shù)的作用就是將發(fā)射者sender對(duì)象中的信號(hào)signal與接收者receiver中的member插槽函數(shù)聯(lián)系起來(lái)。當(dāng)指定信號(hào)signal時(shí)必須使用Qt的宏SIGNAL(),當(dāng)指定插槽函數(shù)時(shí)必須使用宏SLOT()。如果發(fā)射者與接收者屬于同一個(gè)對(duì)象的話,那么在connect()調(diào)用中接收者參數(shù)可以省略。
n 信號(hào)與插槽相關(guān)聯(lián)。
下例定義了兩個(gè)對(duì)象:標(biāo)簽對(duì)象label和滾動(dòng)條對(duì)象scroll,并將valueChanged()信號(hào)與標(biāo)簽對(duì)象的setNum()插槽函數(shù)相關(guān)聯(lián),另外信號(hào)還攜帶了一個(gè)整型參數(shù),這樣標(biāo)簽總是顯示滾動(dòng)條所處位置的值。
QLabel*label=newQLabel;
QScrollBar*scroll=newQScrollBar;
QObject::connect(scroll,SIGNAL(valueChanged(int)),label,SLOT(setNum(int)));
n 信號(hào)與信號(hào)相關(guān)聯(lián)。
在下面的構(gòu)造函數(shù)中,MyWidget創(chuàng)建了一個(gè)私有的按鈕aButton,按鈕的單擊事件產(chǎn)生的信號(hào)clicked()與另外一個(gè)信號(hào)aSignal()進(jìn)行關(guān)聯(lián)。這樣,當(dāng)信號(hào)clicked()被發(fā)射時(shí),信號(hào)aSignal()也接著被發(fā)射。如下所示:
classMyWidget:publicQWidget
{
public:
MyWidget();
...
signals:
voidaSignal();
...
private:
...
QPushButton*aButton;
};
MyWidget::MyWidget()
{
aButton=newQPushButton(this);
connect(aButton,SIGNAL(clicked()),SIGNAL(aSignal()));
}
(4)解除信號(hào)與插槽關(guān)聯(lián)。
當(dāng)信號(hào)與槽沒(méi)有必要繼續(xù)保持關(guān)聯(lián)時(shí),用戶可以使用disconnect()函數(shù)來(lái)斷開(kāi)連接。其定義如下所示:
boolQObject::disconnect(constQObject*sender,constchar*signal,constObject*receiver,constchar*member)[static]
這個(gè)函數(shù)斷開(kāi)發(fā)射者中的信號(hào)與接收者中的槽函數(shù)之間的關(guān)聯(lián)。
有3種情況必須使用disconnect()函數(shù)。
n 斷開(kāi)與某個(gè)對(duì)象相關(guān)聯(lián)的任何對(duì)象。
當(dāng)用戶在某個(gè)對(duì)象中定義了一個(gè)或者多個(gè)信號(hào),這些信號(hào)與另外若干個(gè)對(duì)象中的槽相關(guān)聯(lián),如果想要切斷這些關(guān)聯(lián)的話,就可以利用這個(gè)方法,非常簡(jiǎn)潔。如下所示:
disconnect(myObject,0,0,0)
或者
myObject->disconnect()
n 斷開(kāi)與某個(gè)特定信號(hào)的任何關(guān)聯(lián)。
這種情況是非常常見(jiàn)的,其典型用法如下所示:
disconnect(myObject,SIGNAL(mySignal()),0,0)
或者
myObject->disconnect(SIGNAL(mySignal()))
n 斷開(kāi)兩個(gè)對(duì)象之間的關(guān)聯(lián)。
這也是非常常用的情況,如下所示:
disconnect(myObject,0,myReceiver,0)
或者
myObject->disconnect(myReceiver)
注意 | 在disconnect()函數(shù)中0可以用作一個(gè)通配符,分別表示任何信號(hào)、任何接收對(duì)象、接收對(duì)象中的任何槽函數(shù)。但是發(fā)射者sender不能為0,其他3個(gè)參數(shù)的值可以等于0。 |
linux相關(guān)文章:linux教程
評(píng)論