同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不是使用的原生组件,而是本身绘制模拟的本地组件的样子,不过看看这个截图,它模拟的不能说百分百一致,也可说是唯妙唯肖了… :)