Qt 組件布局

2018-10-04 10:05 更新

組件布局

同 Swing 類似,Qt 也提供了幾種組件定位的技術(shù)。其中就包括絕對定位和布局定位。

顧名思義,絕對定位就是使用最原始的定位方法,給出這個組件的坐標和長寬值。這樣,Qt 就知道該把組件放在哪里,以及怎么設(shè)置組件的大小了。但是這樣做的一個問題是,如果用戶改變了窗口大小,比如點擊了最大化或者拖動窗口邊緣,這時,你就要自己編寫相應的函數(shù)來響應這些變化,以避免那些組件還只是靜靜地呆在一個角落?;蛘?,更簡單的方法是直接禁止用戶改變大小。

不過,Qt 提供了另外的一種機制,就是布局,來解決這個問題。你只要把組件放入某一種布局之中,當需要調(diào)整大小或者位置的時候,Qt 就知道該怎樣進行調(diào)整。這類似于 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 是一個有上下箭頭的微調(diào)器,QSlider 是一個滑動桿,只要運行一下就會明白到底是什么東西了。

代碼并不是那么難懂,還是來簡單的看一下。首先創(chuàng)建了一個 QWidget 的實例,調(diào)用 setWindowTitle 函數(shù)來設(shè)置窗口標題。然后創(chuàng)建了一個 QSpinBox 和 QSlider,分別設(shè)置了它們值的范圍,使用的是 setRange 函數(shù)。然后進行信號槽的鏈接。這點后面再詳細說明。然后是一個QHBoxLayout,就是一個水平布局,按照從左到右的順序進行添加,使用 addWidget 添加好組件后,調(diào)用 QWidget 的 setLayout 把 QWidget 的 layout 設(shè)置為我們定義的這個 Layout,這樣,程序就完成了!

編譯運行一下,可以看到效果:

如果最大化的話:

雖然我并沒有添加任何代碼,但是那個 layout 就已經(jīng)明白該怎樣進行布局。

或許你發(fā)現(xiàn),那兩個信號槽的鏈接操作會不會產(chǎn)生無限遞歸?因為 steValue 就會引發(fā) valueChanged信號!答案是不會。這兩句語句實現(xiàn)了,當 spinBox 發(fā)出 valueChanged 信號的時候,會回調(diào)slider 的 setValue,以更新 slider 的值;而 slider 發(fā)出 valueChanged 信號的時候,又會回調(diào) slider 的 setValue。但是,如果新的 value 和舊的 value 是一樣的話,是不會發(fā)出這個信號的,因此避免了無限遞歸。

迷糊了吧?舉個例子看。比如下面的 spinBox->setValue(35)執(zhí)行的時候,首先,spinBox 會將自己的值設(shè)為35,這樣,它的值與原來的不一樣了(在沒有 setValue 之前的時候,默認值是0),于是它發(fā)出了 valueChanged 信號。slider 接收到這個信號,于是回調(diào)自己的 setValue 函數(shù),將它的值也設(shè)置成35,它也發(fā)出了 valueChanged 信號。當然,此時 spinBox 又收到了,不過它發(fā)現(xiàn),這個35和它本身的值是一樣的,于是它就不發(fā)出信號,所以信號傳遞就停止了。

那么,你會問,它們是怎么知道值的呢?答案很簡單,因為你的信號和槽都接受了一個int參數(shù)!新的值就是通過這個進行傳遞的。實際上,我們利用Qt的信號槽機制完成了一個數(shù)據(jù)綁定,使兩個組件或者更多組件的狀態(tài)能夠同步變化。

Qt 一共有三種主要的 layout,分別是:

QHBoxLayout- 按照水平方向從左到右布局;

QVBoxLayout- 按照豎直方向從上到下布局;

QGridLayout- 在一個網(wǎng)格中進行布局,類似于 HTML 的 table。

layout 使用 addWidget 添加組件,使用 addLayout 可以添加子布局,因此,這就有了無窮無盡的組合方式。

我是在 Windows 上面進行編譯的,如果你要是在其他平臺上面,應用程序就會有不同的樣子:

還記得前面曾經(jīng)說過,Qt 不是使用的原生組件,而是自己繪制模擬的本地組件的樣子,不過看看這個截圖,它模擬的不能說百分百一致,也可說是惟妙惟肖了… :)

本文出自 “豆子空間” 博客,請務(wù)必保留此出處 http://devbean.blog.51cto.com/448512/194031

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號