下面的例子用来说明如何将一个布局包含在另一个布局之内,父布局是一个2x2的QGridLayout.在它的左上角包含了一个QLCDNumber部件,一个QSlider部件占据了最下边的两个单元格.右上角包含了一个QVBoxLayout,其中包含了一个按顺序排列了4个按钮的列
注意:尽管在QGridLayout中放置所有的部件有可能实现几乎任意布局,但是按照这样的方法分割布局将使工作方便很多.在小的组中处理部件可以简化复杂窗口的编程任务.
Main
1 /* main.cpp */
2 #include <kapp.h>
3 #include “layoutlayout.h”
4
5 int main(int argc,char **argv)
6 {
7 KApplication app(argc,argv,”layoutlayout”);
8 LayoutLayout *layoutlayout = new LayoutLayout();
9 layoutlayout->show();
10 app.setMainWidget(layoutlayout);
11 return(app.exec());
12 }
LayoutLayout Header
1 /* layoutlayout.h */
2 #ifndef LAYOUTLAYOUT_H
3 #define LAYOUTLAYOUT_H
4
5 #include <qwidget.h>
6 #include <qlayout.h>
7 #include <qlcdnumber.h>
8 #include <qpushbutton.h>
9 #include <qslider.h>
10
11 class LayoutLayout: public QWidget
12 {
13 public:
14 LayoutLayout(QWidget *parent=0,const char *name=0);
15 ~LayoutLayout() { };
16 private:
17 QLCDNumber *lcd;
18 QPushButton *openButton;
19 QPushButton *saveButton;
20 QPushButton *saveasButton;
21 QPushButton *exitButton;
22 QSlider *slider;
23 };
24
25 #endif
类定义中包含将要显示的6个部件.尽管由不同的布局管理它们的放置位置和大小设置,但它们都是LayoutLayout部件类的成员.在这里要引入两个层次结构,布局的层次结构和部件层次结构是没有关系的.布局的层次结构只能几何上安排部件的位置、设置部件的小小,其他什么也不做;为了实现通用性,在部件树状结构中每个部件必须拥有一个父部件,顶层用作主窗口的部件除外。
LayoutLayout
1 /* layoutlayout.cpp */
2 #include “layoutlayout.h”
3
4 LayoutLayout::LayoutLayout(QWidget *parent,const char *name)
5 : QWidget(parent,name)
6 {
7 QGridLayout *layout = new QGridLayout(this,2,2,3);
8
9 lcd = new QLCDNumber(this);
10 lcd->setNumDigits(2);
11 lcd->display(43);
12 lcd->setMinimumSize(100,100);
13 layout->addWidget(lcd,0,0);
14
15 QVBoxLayout *vertButtonLayout = new QVBoxLayout(3);
16 layout->addLayout(vertButtonLayout,0,1);
17
18 openButton = new QPushButton(“Open”,this);
19 openButton->setMinimumSize(openButton->sizeHint());
20 vertButtonLayout->addWidget(openButton);
21
22 saveButton = new QPushButton(“Save”,this);
23 saveButton->setMinimumSize(saveButton->sizeHint());
24 vertButtonLayout->addWidget(saveButton);
25
26 saveasButton = new QPushButton(“Save As..”,this);
27 saveasButton->setMinimumSize(saveasButton->sizeHint());
28 vertButtonLayout->addWidget(saveasButton);
29
30 exitButton = new QPushButton(“Exit”,this);
31 exitButton->setMinimumSize(exitButton->sizeHint());
32 vertButtonLayout->addWidget(exitButton);
33
34 slider = new QSlider(QSlider::Horizontal,this);
35 slider->setMinimumSize(slider->sizeHint());
36 layout->addMultiCellWidget(slider,1,1,0,1);
37
38 resize(10,10);
39 layout->activate();
40 }
在第7行将主布局栅格创建为2x2,this参数指定了这个类是LayoutLayout对象的主布局对象。同时也创建了栅格布局,在所有包含的项周围插入3个像素点宽的边框。每个将要由此部件显示的项都必须通过这个栅格布局进行定位(尽管可以显示不在布局中的包含的子部件,但是这些部件在窗口中的位置将是不确定的)。
第9行到第13行创建了一个QLCDNumber对象,用来显示两位的数字43,将它安装在栅格的左上角。
第15行创建了一个垂直布局框,这个垂直框没有指定父对象,因为它将作为主布局窗口的子项包含在主布局窗口中。实际上紧接着的第16行,就调用了addLayout()方法将这个垂直框作为一项插入到栅格布局脏右上角中。这样用LayoutLayout对象建立的布局结构层次位于最顶层,在第7行创建的QGridLayout位于它的下一层,而在第15行创建的QVBoxLayout位于第3层。值得注意的是,参数this被用来创建栅格,这样就将它创建为顶层的包容器。this参数没有用来创建垂直框,由此必须调用addLayout()建立它的层次结构。
注意:一个QLayout对象在拥有子部件或者有其它布局插入到其中之前,它必须有一个父对象。主布局窗口必须是包围它的部件的子对象,所有其它的布局都是它的子对象(或者为子对象的子对象)。
第18行到第20行创建了QPushButton,并把它加入到垂直框中。设置了按钮的最小值,没有设置最大值,这样按钮将可以按照需要扩展,以充满垂直框中所占的单元格。第22行到第32行又创建了3个按钮,并将它们加入到垂直框中。这些排成一列的按钮将显示在窗口的右上部。
第34行到第36行创建了QSlider对象,并将它放置到栅格中。它占据两个底部的单元格,像按钮一样,它只设定了最小尺寸,允许扩大充满所占据的栅格布局的单元格。
在第38行调用的resize()保证了最初所产生的大小尺寸是最小值。最小尺寸是由LayoutLayout widget询问QGridLayout的最小尺寸而得来的。QGridLayout查看QLCDNumber、QSlider以及QVBoxLayout的最小尺寸,将它们加在一起(考虑边框间隔),得出自己的最小尺寸。QVBoxLayout的最小尺寸是由每个按钮的最小尺寸之和决定的,然后使用最大的水平值和垂直方向上的总和作为它的最小宽度和最小高度。