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 有空會繼續搞下去的