信號和槽是一種高級接口,應用於對象之間的通信,它是 QT 的核心特性。要正確的處理信號和槽,必須藉助一個稱爲 moc(Meta Object Compiler)的 QT 工具,該工具是一個 C++ 預處理程序,它爲高層次的事件處理自動生成所需要的附加代碼。 信號和槽能攜帶任意數量和任意類型的參數。我們可以將很多信號與單個的槽進行連接,也可以將單個的信號與很多的槽進行連接,(當這個信號被髮射時,這些槽將會一個接一個地 執行,但是它們執行的順序將會是隨機的、不確定的,我們不能人爲地指定哪個先執行、哪個後執行。)甚至於將一個信號與另外一個信號相連接,這時無論第一個信號什麼時候發射系統都將立刻發射第二個信號。總之,信號與槽構造了一個強大的部件編程機制。
信號(Signals)
信號只需要在頭文件中做聲明,不需要在cpp中實現。放在QT自定義關鍵字signals下,在此之前一定要加上Q_OBJECT宏!
在編程中,一般使用的是控件內部定義好的信號。如:QTreeWidget類下的 Signals:
1
2
3
4
5
6
7
8
9
10
|
void currentItemChanged
( QTreeWidgetItem * current, QTreeWidgetItem * previous ) void itemActivated
( QTreeWidgetItem * item, int column
) void itemChanged
( QTreeWidgetItem * item, int column
) void itemClicked
( QTreeWidgetItem * item, int column
) void itemCollapsed
( QTreeWidgetItem * item ) void itemDoubleClicked
( QTreeWidgetItem * item, int column
) void itemEntered
( QTreeWidgetItem * item, int column
) void itemExpanded
( QTreeWidgetItem * item ) void itemPressed
( QTreeWidgetItem * item, int column
) void itemSelectionChanged
() |
也可以自定義信號,並通過emit在代碼中發射信號。
1
2
3
4
|
//
------------ sender.h ----------- class sender
: public QObject { Q_OBJECT |
1
2
3
4
5
6
7
8
9
10
11
|
public : void doSend(); signals: void send( int ); }; //
------------ sender.cpp ----------- #include
"sender.h" void sender
:: doSend() { emit
send(40); } |
槽(Slots)
槽和普通的C++成員函數幾乎是一樣的(可以是虛函數,可以被重載,可以是public slots、protected slots、private slots,可以被其他C++成員函數直接調用;唯一不同的是:槽還可以和信號連接在一起,在這種情況下,信號被髮射時,會自動調用這個槽。)槽不需要信號傳過來的參數時,可以不要參數;但槽一旦要參數,其參數個數,類型,順序必須要和對應的信號保持一致。另外,槽的參數不能有缺省值。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//
------------ receiver.h ----------- class receiver
: public QObject { Q_OBJECT public slots: void recv( int ); }; //
------------ Receiver.cpp ----------- void receiver
:: recv( int n) { qDebug()<< "recv
number: " <<n<<endl; } |
++++ ++++
關聯信號和槽(connect)
可以使用QObject類的靜態成員函數connect來建立信號的槽的關聯
bool QObject::connect
( const QObject
* sender, const char *
signal ,
const QObject
* receiver, const char *
slot) [ static ] |
具體的調用爲:connect(sender, SIGNAL(signal), receiver, SLOT(slot)); 其中sender和receiver爲QObject類對象的指針; SIGNAL宏和SLOT宏將信號的槽轉換成字符串。
1
2
3
|
sender
s; receiver
r; QObject::connect(&s,
SIGNAL(send( int )),
&r, SLOT(recv( int ))); |
注:在connect函數中信號函數和槽函數若有參數,只能寫出參數類型,而不能也將變量名寫出;否則,連接會失敗!
斷開信號和槽(disconnect)
當信號和槽沒有必要繼續保持連接時,可以通過調用disconnect來斷開它們。
bool QObject::disconnect
( const QObject
* sender, const char *
signal ,
const Object
* receiver, const char *
slot) [ static ] |
有三種情況必須使用 disconnect() 函數:
(1)斷開與某個對象相關聯的任何對象。
disconnect(sender,
0, 0, 0) ; //或者 sender->disconnect(); |
(2)斷開與某個特定信號的任何關聯。
disconnect(sender,
SIGNAL( signal ()),
0, 0); //或者 sender->disconnect(SIGNAL( signal ())); |
(3)斷開兩個對象之間的關聯。
disconnect(sender,
0, receiver, 0); //或者 sender->disconnect(receiver); |
更多的請參考:http://www.ibm.com/developerworks/cn/linux/guitoolkit/qt/signal-slot/index.html