Making Connections
在下一個例子當中,將會告訴我們如何對使用者的動作做出回應。這個程式包含了一個按鈕,當使用者點了這個按鈕之後,程式就會離開。這個程式跟 Hello 這隻相當類似,主要差別在於我們用 QPushButton 來代替 QLabel以下是範例:
1 #include <qapplication.h>
2 #include <qpushbutton.h>
3 int main( int argc, char *argv[] )
4 {
5 QApplication app(argc, argv) ;
6 QPushButton *button = new QPushButton("Quit", 0) ;
7 QObject::connect(button, SIGNAL( clicked() ),
8 &app, SLOT( quit() )) ;
9 app.setMainWidget(button) ;
10 button->show() ;
11 return app.exec() ;
12 }
QT 的 widget 透過 signals 表示使用者的動作或者是狀態的改變。舉例來說,QPushButton會在使用者按下按鈕的時候,發出一個 clicked() signal。Signal 可以跟 function 作連結(接下來這個 function 我們會稱作 slot),也就是說,當一個 signal 被發出的時候,slot 就會自動的被執行。
在我們的例子當中,我們把按鈕的 clicked() signal 跟 QApplication 物件的 quit() slot 做了連結,SIGNAL() 以及 SLOT() 這兩個 macros 是 Qt 語法的一部分,在下一章當中會有更詳細的解釋。
接著我們就來 build 並且執行這個程式,當程式執行之後,如果你按下了 Quit,或是按下空白鍵(代表按下 Quit 按鈕),你會發現程式會結束執行。
下一個例子則是展示了如何利用 signals 以及 slots 讓兩個 widget 同步,這個程式詢問使用者的年紀,使用者可以透過一個 spin box 或是 slider 來作輸入。 程式包含了三個 widgets:QSpinBox、QSlider、QHBox (horizontal layout box)。QHBox 是程式的 main widget,QSpinBox 以及 QSlider 被放在 QHBox 裡面,它們兩個是 QHBox 的 children。
1 #include <qapplication.h>
2 #include <qhbox.h>
3 #include <qslider.h>
4 #include <qspinbox.h>
5 int main( int argc, char *argv[] )
6 {
7 QApplication app(argc,argv) ;
8 QHBox *hbox = new QHBox(0) ;
9 hbox->setCaption("Enter Your Age") ;
10 hbox->setMargin(6) ;
11 hbox->setSpacing(6) ;
12 QSpinBox *spinBox = new QSpinBox(hbox) ;
13 QSlider *slider = new QSlider(Qt::Horizontal, hbox) ;
14 spinBox->setRange(0,130) ;
15 slider->setRange(0,130) ;
16 QObject::connect(spinBox, SIGNAL(valueChanged(int)),
17 slider, SLOT(setValue(int))) ;
18 QObject::connect(slider, SIGNAL(valueChanged(int)),
19 spinBox, SLOT(setValue(int))) ;
20 spinBox->setValue(35) ;
21 app.setMainWidget(hbox);
22 hbox->show() ;
23 return app.exec() ;
24 }
第 8 行到第 11 行我們對 QHBox 做了一些設定,我們在 QHBox 的外圍以及跟 child widget 之間留了一些空間 (6 pixels)。12 和 13 行我們產生了行我們產生了 QSpinBox 以及 QSlider 物件,並且把他們兩個的 parent 都設定為 QHBox。
儘管我們沒有明確設定這兩個 widget 的位置以及大小,我們仍然會發現 QSpinBox 還有 QSlider 在 QHBox 當中躺的好好的,這是因為 QHBox 會自動的給他的 child 合理的位置還有大小。Qt 提供了許多像是 QHBox 之類的 classes 讓我們不用刻意去指定 widget 的位置以及大小。
14 以及 15 行設定了 spin box 以及 slider 的合法範圍,16 到 19 行的兩個 connect 則是讓 spin box 以及 slider 作同步的動作,使他們兩個都會有相同的值。當任何一個 widget 的值改變,就會丟出 valueChanged(int) 的 signal,連接到另外一個 widget 的 setValue(int) slot,並且跟著改變值。
第 20 行把 spin box 的值設定為 35,當跑到這一行時,QSpinBox 發出了 valueChanged(int) 的 signal,並且還有一個值為 35 的 int argument。這個 arguemnt 會被傳到 QSlider 的 setValue(int) slot,把 slider 的值設成 35。接著 slider 又會因為 slider 的值改變了而送出一個 valueChanged(int) 的 signal,不過在這個時候,因為 spin box 的值已經是 35 了,所以不會有 setValue(int) 的發生。這樣可以避免無窮迴圈的狀況發生。
總結一下,Qt 建造使用者介面的方法相當簡單易懂而且有彈性,並且透過 layout,我們可以不用擔心 widget 的大小還有位置問題。UI 的行為則是透過 widget 之間的 signals 還有 slots 機制來作管理。
2 意見:
Good job!
Thx! 不過這系列真是很久沒更新了 orz 有空會繼續搞下去的