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