[Qt]常用控件介绍-布局管理器-QVBoxLayout、QHBoxLayout、QGridLayout、QFormLayout、QSpace控件
目录
1.布局管理器
2.垂直布局-VBoxLayout控件
核心属性
核心方法
细节
布局管理器使用前后的界面变化
两个布局管理器的设定
3.水平布局-HBoxLayout控件
核心属性
垂直和水平管理器的嵌套使用
4.网格布局-GridLayout控件
核心属性
细节
SizePolicy属性
使用案例1
使用案例2-设置水平方向拉伸比例
使用案例3-设置竖直方向拉伸系数
5.表单布局-FormLayout控件
细节
使用案例
6.Space控件
属性
使用案例
1.布局管理器
我们平时在使用Qt Designer的时候,在进行手动布局时,是非常不精确的,布局起来非常的麻烦,需要通过绝对定位的方式来设定,计算坐标最后使用setGeometry或者其他方式就行调节控件的位置。而引入布局管理器机制的话,就解决了上述的问题。
在Qt中布局管理器为我们提供了很多种,也就对应了多种布局风格。常见的有垂直布局、水平布局、网格布局、表单布局。
2.垂直布局-VBoxLayout控件
核心属性
属性 | 说明 |
layoutLeftMargin | 左侧边距 |
layoutRightMargin | 右侧边距 |
layoutTopMargin | 上方边距 |
layoutBottonMargin | 下方边距 |
layoutSpacing | 相邻元素之间的边距 |
对于layout只是用于布局属性,不提供任何的信号
核心方法
方法 | 说明 |
addWidget(QWidget*) | 添加一个控件到布局管理器 |
this->setLayout | 将布局管理器添加到窗口中 |
细节
- 对于布局管理器来说,如果添加的控件对象,没有显示的指定父元素,也就是没有挂载到对象树中的时候,布局管理器会自动处理父子关系,将添加的控件的父元素变为和自己一样。所以说对于布局管理器来说,可以不用显示的指定父元素。
- 很多情况下,有添加操作的时候也是不需要指定父元素的,会自动帮我们去构建对象树关系,例如容器类控件内部的元素对象,在添加的时候不需要指定,对于布局管理器也是,当布局管理器被添加到某一个控件下的时候,就不需要指定父元素了。
- 但是指定了父元素之后,也只是挂载到了对象树上,不会自动的设置到窗口中,我们还是要调用setLayout方法去设置到窗口当中的。
- 对于每个widget中只能设置一个布局管理器
布局管理器使用前后的界面变化
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QVBoxLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建三个按钮
QPushButton* button1 = new QPushButton("按钮1");
QPushButton* button2 = new QPushButton("按钮2");
QPushButton* button3 = new QPushButton("按钮3");
//创建布局管理器
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
//将布局管理器添加到窗口中
this->setLayout(layout);
}
Widget::~Widget()
{
delete ui;
}
两个布局管理器的设定
如果说我们在代码中直接设置两个布局管理器的话,不会有任何的效果,还是显示一个布局管理器的效果。我们只能在Qt Designer中使用拖拽的方式定义布局管理器的位置才可以显示出来两个。
如果我们在代码中创建layout的话,就只是创建一个layout,而我们在Qt Designer中的话,是先创建了一个QWidget窗口,之后再创建了一个layout。所以说在Qt Designer中才可以创建多个布局管理器。
3.水平布局-HBoxLayout控件
核心属性
属性 | 说明 |
layoutLeftMargin | 左侧边距 |
layoutRightMargin | 右侧边距 |
layoutTopMargin | 上方边距 |
layoutBottonMargin | 下方边距 |
layoutSpacing | 相邻元素之间的边距 |
垂直和水平管理器的嵌套使用
对于layout可以嵌套进行使用的。
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建按钮
QPushButton* button1 = new QPushButton("按钮1");
QPushButton* button2 = new QPushButton("按钮2");
//创建顶层垂直布局管理器
QVBoxLayout* vLayout = new QVBoxLayout();
vLayout->addWidget(button1);
vLayout->addWidget(button2);
//设置到窗口中
this->setLayout(vLayout);
//创建按钮
QPushButton* button3 = new QPushButton("按钮3");
QPushButton* button4 = new QPushButton("按钮4");
//创建嵌套的水平布局管理器
QHBoxLayout* hLayout = new QHBoxLayout();
hLayout->addWidget(button3);
hLayout->addWidget(button4);
//将水平布局管理器添加到垂直布局管理器当中
vLayout->addLayout(hLayout);
}
Widget::~Widget()
{
delete ui;
}
4.网格布局-GridLayout控件
核心属性
属性 | 说明 |
layoutLeftMargin | 左侧边距 |
layoutRightMargin | 右侧边距 |
layoutTopMargin | 上方边距 |
layoutBottonMargin | 下方边距 |
layoutHorizontalSpacing | 相邻元素之间的水平方向间距 |
layoutVerticalSpacing | 相邻元素之间的垂直方向间距 |
layoutRowStretch | 行方向的拉伸系数 |
layoutColumnStretch | 列方向的拉伸系数 |
细节
- 如案例1所示,如果说添加到布局管理器中的位置设置的太大,而这个值还和上一个值之间并没有其他元素的话,并不会腾出额外的空间,而是直接设置在后面。
- 对于水平拉伸系数的设定,是按照比例来设定的,如案例2所写,拉伸系数的比例就是1:1:2。如果第二个参数设置为0的话,就是固定的大小,不参与拉伸。
- 而竖直拉伸系数的设定,按照案例2的方法设置效果会很不明显,因为每个按钮的高度是固定的,需要按钮的垂直方向的sizePolicy属性设置为QSizePolicy::Expanding尽可能的填充满布局管理器才能看到效果。
- 这个sizePolicy是控件的一个属性
SizePolicy属性
属性 | 说明 |
QSizePolicy::Ignored | 忽略控件的尺寸,不对布局产生影响,也就是听从布局管理器的设定 |
QSizePolicy::Minimum | 控件的最小尺寸 |
QSizePolicy::Maximum | 控件的最大尺寸 |
QSizePolicy::Preferred | 控件的理想尺寸,布局时会尽量接近该值 |
QSizePolicy::Expanding | 控件的尺寸根据空间调整,尽可能占据更大的空间 |
QSizePolicy::Shrinkling | 空间的尺寸根据空间调整,尽可能的缩小适应空间 |
使用案例1
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QGridLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建按钮
QPushButton* button1 = new QPushButton("按钮1");
QPushButton* button2 = new QPushButton("按钮2");
QPushButton* button3 = new QPushButton("按钮3");
QPushButton* button4 = new QPushButton("按钮4");
//创建网格布局管理器
QGridLayout* layout = new QGridLayout();
layout->addWidget(button1, 0, 0);
layout->addWidget(button2, 1, 1);
layout->addWidget(button3, 2, 2);
layout->addWidget(button4, 10, 10);
//设置到窗口中
this->setLayout(layout);
}
Widget::~Widget()
{
delete ui;
}
使用案例2-设置水平方向拉伸比例
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QGridLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建按钮
QPushButton* button1 = new QPushButton("按钮1");
QPushButton* button2 = new QPushButton("按钮2");
QPushButton* button3 = new QPushButton("按钮3");
QPushButton* button4 = new QPushButton("按钮4");
QPushButton* button5 = new QPushButton("按钮5");
QPushButton* button6 = new QPushButton("按钮6");
//创建网格布局管理器
QGridLayout* layout = new QGridLayout();
layout->addWidget(button1, 0, 0);
layout->addWidget(button2, 0, 1);
layout->addWidget(button3, 0, 2);
layout->addWidget(button4, 1, 0);
layout->addWidget(button5, 1, 1);
layout->addWidget(button6, 1, 2);
//设置到窗口中
this->setLayout(layout);
//设置水平的拉伸系数
layout->setColumnStretch(0, 1);
layout->setColumnStretch(1, 1);
layout->setColumnStretch(2, 2);
}
Widget::~Widget()
{
delete ui;
}
使用案例3-设置竖直方向拉伸系数
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QGridLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建按钮
QPushButton* button1 = new QPushButton("按钮1");
QPushButton* button2 = new QPushButton("按钮2");
QPushButton* button3 = new QPushButton("按钮3");
QPushButton* button4 = new QPushButton("按钮4");
QPushButton* button5 = new QPushButton("按钮5");
QPushButton* button6 = new QPushButton("按钮6");
//设置按钮的拉伸状态
button1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
button2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
button3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
button4->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
button5->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
button6->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
//创建网格布局管理器
QGridLayout* layout = new QGridLayout();
layout->addWidget(button1, 0, 0);
layout->addWidget(button2, 0, 1);
layout->addWidget(button3, 1, 0);
layout->addWidget(button4, 1, 1);
layout->addWidget(button5, 2, 0);
layout->addWidget(button6, 2, 1);
//设置到窗口中
this->setLayout(layout);
//设置垂直的拉伸系数
layout->setRowStretch(0, 1);
layout->setRowStretch(1, 0);
layout->setRowStretch(2, 3);
}
Widget::~Widget()
{
delete ui;
}
5.表单布局-FormLayout控件
该控件相当于是QGridLayout的一个特殊情况,专门用于实现n行两列的一个布局。
细节
- 当第一列设置为nullptr的时候,就不会显示任何内容了
- 第一列固定就是一个文本label,第二列是一些按钮、菜单等等内容都可以。
使用案例
#include "widget.h"
#include "ui_widget.h"
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QFormLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建表单中的元素
QPushButton* button = new QPushButton("提交");
QLineEdit* line1 = new QLineEdit();
QLineEdit* line2 = new QLineEdit();
QLabel* label1 = new QLabel("姓名");
QLabel* label2 = new QLabel("电话");
//创建表单管理器
QFormLayout* layout = new QFormLayout();
layout->addRow(label1, line1);
layout->addRow(label2, line2);
layout->addRow(nullptr, button);
this->setLayout(layout);
}
Widget::~Widget()
{
delete ui;
}
6.Space控件
他并非是一个布局管理器,但是通常要搭配布局管理器去使用,在使用布局管理器的时候,里面的控件之间的间隔会很近,如果我们想要在控件之间添加一段空白,可以使用QSpaceItem对象来表示。
属性
属性 | 说明 |
width | 宽度 |
height | 高度 |
hData | 水平方向的sizePolicy |
vData | 竖直方向的sizePolicy |
使用案例
#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QHBoxLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建两个按钮
QPushButton* button1 = new QPushButton("按钮1");
QPushButton* button2 = new QPushButton("按钮2");
//创建水平布局管理器
QHBoxLayout* layout = new QHBoxLayout();
//创建space
QSpacerItem* space = new QSpacerItem(200, 100);
layout->addWidget(button1);
layout->addSpacerItem(space);
layout->addWidget(button2);
this->setLayout(layout);
}
Widget::~Widget()
{
delete ui;
}