From Gossip@caterpillar

Qt3 Gossip: 簡單的 Signal 與 Slot

在前一個範例中,我們使用QApplication物件的setMainWidget()設定主Widget,讓它幫我們在按下視窗關閉鈕結束事件迴圈以結束程式,而在這邊我們將使用Qt中相當重要的機制Signals與Slots來處理關閉視窗的動作。

首先我們撰寫以下的程式:
  • hello.cpp
#include <qapplication.h>

int main(int argc, char **argv) {
QApplication app(argc, argv);
QWidget *mainwin = new QWidget();

mainwin->setCaption("Simple signal and slot");
mainwin->resize(200, 150);
app.connect(&app, SIGNAL(lastWindowClosed()),
&app, SLOT(quit()));
mainwin->show();

return app.exec();
}

這個程式的作用與上一個範例是相同的,而程式碼方面其實也只有這行不同:
app.connect(&app, SIGNAL(lastWindowClosed()),
            &app, SLOT(quit()));

這行的目的,將QApplication物件app的Signal - lastWindowClosed()連接至它自己的Slot - quit(),白話點說,當您按下關閉鈕時,app會發出信號通知quit()來關閉程式。

如果您曾學過其它的視窗程式,您會覺得這是不是事件處理?但其實完全不同,接下來對Signals與Slots的說明,將從Qt的線上說明文件中擷取較簡單部份整理並列於以下。

在一個使用者圖形介面(GUI)程式中,我們經常希望某個物件的狀態改變時,可以通知另一個物件進行某些處理或狀態改變,而Signals與Slots就是被用於兩個物件之間的溝通,例如在Qt中兩個Widget之間的溝通就是使用這種機制。

當某一個特定事件發生的時候,Qt會發射(emit)相對應(或定義好的)的Signals,在Qt中有許多預先定義好的Signals,像是 lastWindowClosed() 這個Signal就是事先定義好的,而也有許多事先定義好的Slots,以後您也會學到如何定義自己的Signals與Slots。

Slots是C++的函式(function),我們利用connect()方法將A物件的Signal連接至B物件Slot(也可以是同一個物件),當A物件發生我們感興趣的Signal時,就會直接呼叫連接至這個Signal的Slot來執行。

相較於事件處理而言,Signals與Slots的機制會稍微有效率一些,因為Signal發生時會直接呼叫Slot(一個純綷的函式),這相較於事件處 理中,我們還必須尋找登記好的事件處理者而有所差異;Signals與Slots是立即反應的,而相較於作業系統對事件處理反應時間的不一,效率稍微高了 一些。

在這個程式中, lastWindowClosed()與quit()是QApplication預先定義好的,當按下關閉鈕時會發出Signal - lastWindowClosed(),而連接至它的Slot - quit()會立即執行,所以程式就終止了。