QVBoxLayOut
之前将控件放在界面上,都是通过手动的方式进行的,这种方式不精确,也无法对窗口大小进行自动识别。
Qt引入了布局管理器,具体控件的大小、位置不需要我们手动设置,自动帮我们算好了。
QVBoxLayOut
表示垂直的布局管理器,V是vertical
的缩写
核心属性:
属性 | 说明 |
---|---|
layoutLeftMargin | 左侧边距 |
layoutRightMargin | 右侧边距 |
layoutTopMargin | 上方边距 |
layoutButtonMargin | 下方边距 |
layoutSpacing | 相邻元素直接的边距 |
Layout
只是用于布局,并没有提供信号
代码创建
#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
#include<QVBoxLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建3个按钮,采用布局管理器管理
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;
}
这样就自动设置好了按钮的位置和大小。
图形化创建
上面一个widget
只能设置一个布局管理器。
这图形化界面当中设置,发现可以创建2个布局管理器,但是如果调整窗口大小,这个并不会随着变化。
这是因为使用代码创建layout,其实只创建了一个layout;
如果在Qt Designer中创建的layout,是先创建了widget,然后再新的widget中添加了一个layout。
先拖拽控件,再layout:
这里也可以设置layout的一些属性:
QHBoxLayout
QHBoxLayout
表示水平垂直的布局管理器
属性和QVBoxLayout
一样,使用也是类似
#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");
QPushButton* button3 = new QPushButton("按钮3");
QHBoxLayout* layout = new QHBoxLayout(this);
layout->addWidget(button1);
layout->addWidget(button2);
layout->addWidget(button3);
}
Widget::~Widget()
{
delete ui;
}
布局管理器嵌套
#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
#include<QHBoxLayout>
#include<QVBoxLayout>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建垂直布局管理器
QVBoxLayout* vLayout = new QVBoxLayout();
this->setLayout(vLayout);
//添加按钮
QPushButton* button1 = new QPushButton("按钮1");
QPushButton* button2 = new QPushButton("按钮2");
vLayout->addWidget(button1);
vLayout->addWidget(button2);
//创建水平布局管理器
QHBoxLayout* hLayout = new QHBoxLayout();
QPushButton* button3 = new QPushButton("按钮3");
QPushButton* button4 = new QPushButton("按钮4");
hLayout->addWidget(button3);
hLayout->addWidget(button4);
//水平布局管理器添加到垂直
vLayout->addLayout(hLayout);
}
Widget::~Widget()
{
delete ui;
}
QGridLayout
QGridLayout
用来实现网格布局的效果,可以达到n*m这种网格的效果
核心属性:
属性 | 说明 |
---|---|
layoutLeftMargin | 左侧边距 |
layoutRightMargin | 右侧边距 |
layoutTopMargin | 上方边距 |
layoutButtonMargin | 下方边距 |
layoutHorizontalSpacing | 相邻元素之间的水平方向的间距 |
layoutVerticalSpacing | 相邻元素之间垂直方向的间距 |
layoutRowStretch | 行方向的拉伸系数 |
layoutColunmStretch | 列方向的拉伸系数 |
代码示例
#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");
QPushButton* button7 = new QPushButton("按钮7");
QPushButton* button8 = new QPushButton("按钮8");
QGridLayout* layout = new QGridLayout();
layout->addWidget(button1, 0, 0);
layout->addWidget(button2, 0, 1);
layout->addWidget(button3, 0, 2);
layout->addWidget(button4, 0, 4);
layout->addWidget(button5, 1, 0);
layout->addWidget(button6, 1, 1);
layout->addWidget(button7, 3, 1);
layout->addWidget(button8, 4, 0);
this->setLayout(layout);
}
Widget::~Widget()
{
delete ui;
}
**Tips:**这里设置的行数和列数,只是用来决定控件之间的相对位置
拉伸系数
上面创建的布局管理器,控件尺寸都是一样的,如果想实现不同的尺寸控件,可以通过拉伸系数设置控件尺寸的比例。
水平方向:
#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);
//设置水平方向的拉伸系数 按照1:1:2
layout->setColumnStretch(0, 1);
layout->setColumnStretch(1, 1);
layout->setColumnStretch(2, 2);
}
Widget::~Widget()
{
delete ui;
}
**Tips:**如果
layout->setColumnStretch(0, 0);
第二个参数为0,表示不参与拉伸,一直都是固定尺寸。
垂直方向:
这里直接设置,是无效的,收到了SizePolicy
的影响:
属性 | 说明 |
---|---|
QSizePolicy::Ignored | 忽略按钮的尺寸,不对布局产生影响 |
QSizePolicy::Minimum | 控件的最小尺寸固定在,布局时不会小于该值 |
QSizePolicy::Maximum | 控件的最大尺寸固定值,布局时不会大于该值 |
QSizePolicy::Preferred | 控件的理想尺寸为固定值,布局时会尽量接近该值 |
QSizePolicy::Expanding | 控件的尺寸可以根据控件调整,尽可能占据空间 |
QSizePolicy::Shrinking | 控件尺寸可以根据空间调整,尽可能缩小以适应空间 |
由于按钮的垂直方向默认没有拉伸开(水平方向默认拉伸),所以不会收到拉伸系数的影响,要想让垂直方向的拉伸系数生效,就就需要让按钮能够拉伸开
#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(0, 2);
layout->setRowStretch(0, 3);
}
Widget::~Widget()
{
delete ui;
}
QFormLayout
QFormLayout
叫做表单布局,属于QGridLayout
的一种特殊情况。
它只有n行2列,可由于用户填表的场景
#include "widget.h"
#include "ui_widget.h"
#include<QFormLayout>
#include<QLabel>
#include<QLineEdit>
#include<QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QFormLayout* layout = new QFormLayout();
this->setLayout(layout);
//创建2个label作为第一列
QLabel* label1 = new QLabel("姓名");
QLabel* label2 = new QLabel("学号 ");
//创建2个输入框作为第二列
QLineEdit* edit1 = new QLineEdit();
QLineEdit* edit2 = new QLineEdit();
//上述控件添加到表单
layout->addRow(label1, edit1);
layout->addRow(label2, edit2);
QPushButton* button = new QPushButton("提交");
layout->addRow(nullptr, button);
}
Widget::~Widget()
{
delete ui;
}
QSpacerItem
QSpacerItem
不是布局管理器,但是可以搭配布局管理器使用,用来添加一段空白
属性 | 说明 |
---|---|
width | 宽度 |
height | 高度 |
hData | 水平方向的sizePolicy:QSizePolicy::Ignored :忽略按钮的尺寸,不对布局产生影响QSizePolicy::Minimum :控件的最小尺寸固定在,布局时不会小于该值QSizePolicy::Maximum :控件的最大尺寸固定值,布局时不会大于该值QSizePolicy::Preferred :控件的理想尺寸为固定值,布局时会尽量接近该值QSizePolicy::Expanding :控件的尺寸可以根据控件调整,尽可能占据空间QSizePolicy::Shrinking :控件尺寸可以根据空间调整,尽可能缩小以适应空间 |
vDate | 垂直方向的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);
QHBoxLayout* layout = new QHBoxLayout();
this->setLayout(layout);
QPushButton* button1 = new QPushButton("按钮1");
QPushButton* button2 = new QPushButton("按钮2");
//创建spacer
QSpacerItem* spacer = new QSpacerItem(200, 20); //宽度和高度
//如果想让空白在直接,添加的顺序就在中间
layout->addWidget(button1);
layout->addSpacerItem(spacer);
layout->addWidget(button2);
}
Widget::~Widget()
{
delete ui;
}