[Qt笔记]窗口布局
2011-07-11 22:30:12| 分类: QT | 标签: |字号大中小 订阅
布局是Qt用来管理窗口内的子窗口的一种主法,布局本身不是窗口,它类似于一个虚拟的看不见的容器,可以自动调整其内的子窗口或子布局的大小和位置。
布局统一由QLayout类代表,以它作为基类,派生出所有具体的布局类型。其中常用的布局有水平布局、垂直布局和栅格布局,它们公别由QHBoxLayout类、QVBoxLayout类和QGridLayout类代表。这些类的继承关系如图所示:
|---------------------QLayout-------------------------|
|--------------QBoxLayout-------------| QGridLayout
QHBoxLayout QVBoxLayout
1.1 水平布局和垂直布局
布局内的各个子窗口按照水平或垂直的方式排列。这里用一个例程来说明它们的使用。例程共有三个源文件:main.cpp、mywidget.h、mywidget.cpp,如下所示:
//文件名:main.cpp
//说明:水平布局和垂直布局例程主模块
#include <QApplication>
#include "mywidget.h"
//文件名:main.cpp
//说明:水平布局和垂直布局例程主模块
int main(int argc , char * argv[])
{
QApplication app(argc,argv);
MyWidget wdg;
wdg.show();
return app.exec();
}
主模块仍然是先生成QApplication对象,后生成窗口,然后显示窗口并启动主事件循环的模式,只不过窗口换成了自定认的窗口类MyWidget。这个类的定义在mywidget.h文件中。
//文件名:mywidget.h
//说明:水平布局和垂直布局例程Mywidget类定义
#ifndef MYWIDGET_H
#define MYWIDGET_H
//文件名:mywidget.h
//说明:水平布局和垂直布局例程Mywidget类定义
#include <QWidget>
//以下为类的前向声明
class QHBoxLayout;
class QVBoxLayout;
class QPushButton;
class QLabel;
class MyWidget: public QWidget
{ //MyWidget类继承QWidget类
public:
MyWidget(); //构造函数
virtual ~MyWidget(); //析构函数
protected:
QHBoxLayout *layoutH;
QVBoxLayout *layoutV;
QPushButton *button;
QLabel *label1 , *label2;
};
#endif // MYWIDGET_H
这个类里定义了几个保护权限的成员变量,这些变量都是指向布局或者子窗口的指针。这里,QPushButton类代表按钮,QLayout类代表标签,它们都是QWidget类的子类,因而都属于窗口类,但通常这些类不作为独立窗口出现,而是依附于其它窗口之上,因而常称为窗口部件。为了定义这些类的指针,必须对它们进行类的前向声明。当然,直接包含这些类的头文件也可以,但是这样会造成预处理之后的文件过大。编程的原则是只在必要的时候才包含头文件。
MyWidget类的实现在源文件mywidget.cpp中。
//文件名:mywidget.cpp
//说明:水平布局和垂直布局例程MyWidget类实现
//文件名:mywidget.cpp
//说明:水平布局和垂直布局例程MyWidget类实现
#include "mywidget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
MyWidget::MyWidget()
{
setWindowTitle("Layout"); //设置窗口标题
layoutH = new QHBoxLayout(this); //生成水平布局,并把它设为顶层布局
//layoutH = new QHBoxLayout;
//setLayout(layoutH);
button = new QPushButton("PushButton"); //生成按钮
layoutH->addWidget(button); //将按钮放入水平布局
layoutV=new QVBoxLayout; //生成垂直布局
layoutH->addLayout(layoutV); //将垂直布局加入水平布局中
label1=new QLabel("Label One"); //生成标签1
layoutV->addWidget(label1); //将标签1放入垂直布局
label2=new QLabel("Label Two"); //生成标签2
layoutV->addWidget(label2); //将标签2放入垂直布局
}
MyWidget::~MyWidget()
{
}
在这里,窗口内所有的部件都在构造函数内生成。首先生成一个水平布局,然后又生成一个按钮放入水平布局内,再生成一个垂直布局放入水平布局内。在垂直布局内又先后放入了两个标签。需要注意的是,布局并不是窗口类,因此布局内放入窗口部件和布局内放入布局的函数是不同的,一个是addWidget,一个是addLayout。
对于一个窗口来说,只能有一个布局能成为它的顶级布局,这可以通过向布局的构造函数传递QWidget类的指针来实现,也可以通过QWidget类的以下成员函数实现:
void setLayout(QLayout *layout);
这个函数可以将布局layout设为窗口的顶级布局。
1.2 栅格布局
这种布局将窗口划分为大小相等的若干个区域,每个区域内可以放入一个窗口部件或子布局。
//文件名:mywidget.h
//说明:栅格布局例程MyWidget类定义
#ifndef MYWIDGET_H
#define MYWIDGET_H
//文件名:mywidget.h
//说明:水平布局和垂直布局例程Mywidget类定义
#include <QWidget>
//以下为类的前向声明
class QGridLayout;
class QPushButton;
class QLabel;
class MyWidget: public QWidget
{ //MyWidget类继承QWidget类
public:
MyWidget(); //构造函数
virtual ~MyWidget(); //析构函数
protected:
QGridLayout *layoutG;
QPushButton *button1,*button2;
QLabel *label1 , *label2;
};
#endif // MYWIDGET_H
//文件名:mywidget.cpp
//说明:栅格布局例程MyWidget类实现
//文件名:mywidget.cpp
//说明:水平布局和垂直布局例程MyWidget类实现
#include "mywidget.h"
#include <QGridLayout>
#include <QPushButton>
#include <QLabel>
MyWidget::MyWidget()
{
setWindowTitle("Layout"); //设置窗口标题
layoutG = new QGridLayout(this); //生成水平布局
//layout = new QGridLayout;
//setLayout(layoutH);
button1 = new QPushButton("PushButton One"); //生成按钮
button2 = new QPushButton("PushButton Two");
label1=new QLabel("Label One"); //生成标签1
label2=new QLabel("Label Two"); //生成标签2
layoutG->addWidget(label1,0,0);
layoutG->addWidget(label2,0,1);
layoutG->addWidget(button1,1,0);
layoutG->addWidget(button2,1,1);
}
MyWidget::~MyWidget()
{
}
注意:栅格布局里addWidget函数原型不同,要指明行、列号。
栅格布局内也可以嵌套其他布局:
void addLayout(QLayout *layout , int row , int column)