W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
同 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
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: