Qt學習之路(5):組件佈局

同Swing相似,Qt也提供了幾種組件定位的技術。其中就包括絕對定位和佈局定位。
 
顧名思義,絕對定位就是使用最原始的定位方法,給出這個組件的座標和長寬值。這樣,Qt就知道該把組件放在哪裏,以及怎麼設置組件的大小了。可是這樣作的一個問題是,若是用戶改變了窗口大小,好比點擊了最大化或者拖動窗口邊緣,這時,你就要本身編寫相應的函數來響應這些變化,以免那些組件還只是靜靜地呆在一個角落。或者,更簡單的方法是直接禁止用戶改變大小。
 
不過,Qt提供了另外的一種機制,就是佈局,來解決這個問題。你只要把組件放入某一種佈局之中,當須要調整大小或者位置的時候,Qt就知道該怎樣進行調整。這相似於Swing的佈局管理器,不過Qt的佈局沒有那麼多,只有有限的幾個。
 
來看一下下面的例子:
 
#include <QtGui/QApplication>
#include <QtGui/QWidget>
#include <QtGui/QSpinBox>
#include <QtGui/QSlider>
#include <QtGui/QHBoxLayout>

int main( int argc, char *argv[])
{
        QApplication app(argc, argv);
        QWidget *window = new QWidget;
        window->setWindowTitle( "Enter your age");

        QSpinBox *spinBox = new QSpinBox;
        QSlider *slider = new QSlider(Qt::Horizontal);
        spinBox->setRange(0, 130);
        slider->setRange(0, 130);

        QObject::connect(slider, SIGNAL(valueChanged( int)), spinBox, SLOT(setValue( int)));
        QObject::connect(spinBox, SIGNAL(valueChanged( int)), slider, SLOT(setValue( int)));
        spinBox->setValue(35);

        QHBoxLayout *layout = new QHBoxLayout;
        layout->addWidget(spinBox);
        layout->addWidget(slider);
        window->setLayout(layout);

        window->show();

         return app.exec();
}
 
這裏使用了兩個新的組件:QSpinBox和QSlider,以及一個新的頂級窗口QWidget。QSpinBox是一個有上下箭頭的微調器,QSlider是一個滑動杆,只要運行一下就會明白究竟是什麼東西了。
 
代碼並非那麼難懂,仍是來簡單的看一下。首先建立了一個QWidget的實例,調用setWindowTitle函數來設置窗口標題。而後建立了一個QSpinBox和QSlider,分別設置了它們值的範圍,使用的是setRange函數。而後進行信號槽的連接。這點後面再詳細說明。而後是一個QHBoxLayout,就是一個水平佈局,按照從左到右的順序進行添加,使用addWidget添加好組件後,調用QWidget的setLayout把QWidget的layout設置爲咱們定義的這個Layout,這樣,程序就完成了!
 
編譯運行一下,能夠看到效果:
 
 
若是最大化的話:
 
 
雖然我並無添加任何代碼,可是那個layout就已經明白該怎樣進行佈局。
 
或許你發現,那兩個信號槽的連接操做會不會產生無限遞歸?由於steValue就會引起valueChanged信號!答案是不會。這兩句語句實現了,當spinBox發出valueChanged信號的時候,會回調slider的setValue,以更新slider的值;而slider發出valueChanged信號的時候,又會回調slider的setValue。可是,若是新的value和舊的value是同樣的話,是不會發出這個信號的,所以避免了無限遞歸。
 
迷糊了吧?舉個例子看。好比下面的spinBox->setValue(35)執行的時候,首先,spinBox會將本身的值設爲35,這樣,它的值與原來的不同了(在沒有setValue以前的時候,默認值是0),因而它發出了valueChanged信號。slider接收到這個信號,因而回調本身的setValue函數,將它的值也設置成35,它也發出了valueChanged信號。固然,此時spinBox又收到了,不過它發現,這個35和它自己的值是同樣的,因而它就不發出信號,因此信號傳遞就中止了。
 
那麼,你會問,它們是怎麼知道值的呢?答案很簡單,由於你的信號和槽都接受了一個int參數!新的值就是經過這個進行傳遞的。實際上,咱們利用Qt的信號槽機制完成了一個數據綁定,使兩個組件或者更多組件的狀態可以同步變化。
 
Qt一共有三種主要的layout,分別是:
 
QHBoxLayout- 按照水平方向從左到右佈局;
 
QVBoxLayout- 按照豎直方向從上到下佈局;
 
QGridLayout- 在一個網格中進行佈局,相似於HTML的table。
 
layout使用addWidget添加組件,使用addLayout能夠添加子佈局,所以,這就有了無窮無盡的組合方式。
 
我是在Windows上面進行編譯的,若是你要是在其餘平臺上面,應用程序就會有不一樣的樣子:
 
 
還記得前面曾經說過,Qt不是使用的原生組件,而是本身繪製模擬的本地組件的樣子,不過看看這個截圖,它模擬的不能說百分百一致,也可說是唯妙唯肖了… :)
相關文章
相關標籤/搜索