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