布局管理器
- 1. 布局管理器
- 2. QVBoxLayout——垂直布局
- 3. QHBoxLayout——水平布局
- 4. QGridLayout——网格布局
- 5. QFormLayout——表单布局
- 6. QSpacer
1. 布局管理器
在我们之前值ui界面进行拖拽设置控件时,都是通过手动的控制控件的位置的。同时每个控件的位置都是要计算坐标,最终通过setGeometry或者move方法来进行摆放的,这种设定方式其实并不方便.尤其是界面如果内容比较多的时候,不好计算.而且⼀个窗口大小往往是可以调整的,按照绝对定位的方式,也无法自适应窗口大小,因此Qt引入了布局管理器“LayOut"机制
2. QVBoxLayout——垂直布局
核心属性:
属性 | 说明 |
---|---|
layoutLeftMargin | 左侧边距 |
layoutRightMargin | 右侧边距 |
layoutTopMargin | 上方边距 |
layoutBottomMargin | 下方边距 |
layoutSpacing | 相邻元素之间的间距 |
代码样例:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 创建三个按钮
QPushButton* but1 = new QPushButton("按钮一");
QPushButton* but2 = new QPushButton("按钮二");
QPushButton* but3 = new QPushButton("按钮三");
// 创建布局管理器,并把三个按钮添加到里面
QVBoxLayout* layout = new QVBoxLayout();
layout->addWidget(but1);
layout->addWidget(but2);
layout->addWidget(but3);
// 将布局管理器不知道widget中
this->setLayout(layout);
}
运行程序,可以看到此时界面上的按钮就存在于布局管理器中.随着窗口尺寸变化二发发改变.此时三个按钮的尺寸和位置,都是自动计算出来的.
通过上述代码的方式,只能给这个widget设定⼀个布局管理器.实际上也可以通过Qt Design在⼀个窗口中创建多个布局管理器.
但是当我们运行起来的时候,我们会发现当我们改变窗口大小的时候,这个布局管理器的大小并不会发生改变。这其实是因为我们使用Qt Designer创建布局管理器的时候其实实现创建了一个Widget,设置了geometry属性后才把这个layout设置到widget中,二实际上一个widget只能包含一个layout
3. QHBoxLayout——水平布局
二QHBoxLayout其实和QVBoxLayout属性是一致的,用法也是一致的。
属性 | 说明 |
---|---|
layoutLeftMargin | 左侧边距 |
layoutRightMargin | 右侧边距 |
layoutTopMargin | 上方边距 |
layoutBottomMargin | 下方边距 |
layoutSpacing | 相邻元素之间的间距 |
代码样例1:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 创建三个按钮
QPushButton* but1 = new QPushButton("按钮一");
QPushButton* but2 = new QPushButton("按钮二");
QPushButton* but3 = new QPushButton("按钮三");
// 创建布局管理器,并把三个按钮添加到里面
QHBoxLayout* layout = new QHBoxLayout();
layout->addWidget(but1);
layout->addWidget(but2);
layout->addWidget(but3);
// 将布局管理器不知道widget中
this->setLayout(layout);
}
代码样例2:也可以支持嵌套布局
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPushButton* but1 = new QPushButton("but1");
QPushButton* but2 = new QPushButton("but2");
QVBoxLayout* vlayout = new QVBoxLayout();
vlayout->addWidget(but1);
vlayout->addWidget(but2);
this->setLayout(vlayout);
QPushButton* but3 = new QPushButton("but3");
QPushButton* but4 = new QPushButton("but4");
QHBoxLayout* hlayout = new QHBoxLayout();
hlayout->addWidget(but3);
hlayout->addWidget(but4);
vlayout->addLayout(hlayout);
}
4. QGridLayout——网格布局
QGridLayout和QVBoxLayout,QHBoxLayout的用法相似,只不过QGridLayout是有行列的。
核心属性:
属性 | 说明 |
---|---|
layoutLeftMargin | 左侧边距 |
layoutRightMargin | 右侧边距 |
layoutTopMargin | 上方边距 |
layoutBottomMargin | 下方边距 |
layoutHorizontalSpacing | 相邻元素之间水平方向的间距 |
layoutVerticalSpacing | 相邻元素之间垂直方向的间距 |
layoutRowStretch | 行方向的拉伸系数 |
layoutColumnStretch | 列方向的拉伸系数 |
代码样例:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPushButton* but1 = new QPushButton("but1");
QPushButton* but2 = new QPushButton("but2");
QPushButton* but3 = new QPushButton("but3");
QGridLayout* layout = new QGridLayout();
layout->addWidget(but1, 0, 0);
layout->addWidget(but2, 1, 1);
layout->addWidget(but3, 2, 2);
this->setLayout(layout);
}
我们也可以对布局进行设置拉伸系数,也就是按一定的比例进行布局。
代码样例:水平方向设置拉伸系数
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 创建 6 个按钮
QPushButton* btn1 = new QPushButton("按钮1");
QPushButton* btn2 = new QPushButton("按钮2");
QPushButton* btn3 = new QPushButton("按钮3");
QPushButton* btn4 = new QPushButton("按钮4");
QPushButton* btn5 = new QPushButton("按钮5");
QPushButton* btn6 = new QPushButton("按钮6");
// 创建⽹格布局管理器, 并且添加元素
QGridLayout* layout = new QGridLayout();
layout->addWidget(btn1, 0, 0);
layout->addWidget(btn2, 0, 1);
layout->addWidget(btn3, 0, 2);
layout->addWidget(btn4, 1, 0);
layout->addWidget(btn5, 1, 1);
layout->addWidget(btn6, 1, 2);
// 设置拉伸⽐例
// 第 0 列拉伸⽐例设为 1;
layout->setColumnStretch(0, 1);
// 第 1 列拉伸⽐例设为 0, 即为固定⼤⼩, 不参与拉伸
layout->setColumnStretch(1, 0);
// 第 2 列拉伸⽐例设为 3, 即为第 2 列的宽度是第 0 列的 3 倍
layout->setColumnStretch(2, 3);
// 设置 layout 到窗⼝中.
this->setLayout(layout);
}
另外,QGridLayout 也提供了setRowStretch 设置行之间的拉伸系数.上述案例中,直接设置setRowStretch 效果不明显,因为每个按钮的高度是固定的.需要把按钮的垂直方向的sizePolicy 属性设置为QSizePolicy::Expanding 尽可能填充满布局管理器,才能看到效果.
使用setSizePolicy 设置按钮的尺寸策略. 可选的值如下:
- QSizePolicy::Ignored : 忽略控件的尺寸,不对布局产生影响。
- QSizePolicy::Minimum :控件的最小尺寸为固定值,布局时不会超过该值。
- QSizePolicy::Maximum :控件的最大尺寸为固定值,布局时不会小于该值。
- QSizePolicy::Preferred :控件的理想尺寸为固定值,布局时会尽量接近该值。
- QSizePolicy::Expanding :控件的尺寸可以根据空间调整,尽可能占据更多空间
- QSizePolicy::Shrinking :控件的尺寸可以根据空间调整,尽可能缩小以适应空间。
代码样例:处置方向上设置拉伸系数
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 创建 6 个按钮
QPushButton* btn1 = new QPushButton("按钮1");
QPushButton* btn2 = new QPushButton("按钮2");
QPushButton* btn3 = new QPushButton("按钮3");
QPushButton* btn4 = new QPushButton("按钮4");
QPushButton* btn5 = new QPushButton("按钮5");
QPushButton* btn6 = new QPushButton("按钮6");
// 设置按钮的 sizePolicy, 此时按钮的⽔平⽅向和垂直⽅向都会尽量舒展开
btn1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
btn2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
btn3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
btn4->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
btn5->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
btn6->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
// 创建⽹格布局管理器, 并且添加元素
QGridLayout* layout = new QGridLayout();
layout->addWidget(btn1, 0, 0);
layout->addWidget(btn2, 0, 1);
layout->addWidget(btn3, 1, 0);
layout->addWidget(btn4, 1, 1);
layout->addWidget(btn5, 2, 0);
layout->addWidget(btn6, 2, 1);
// 设置拉伸⽐例
// 第 0 ⾏拉伸⽐例设为 1;
layout->setRowStretch(0, 1);
// 第 1 ⾏拉伸⽐例设为 0, 即为固定⼤⼩, 不参与拉伸
layout->setRowStretch(1, 0);
// 第 2 ⾏拉伸⽐例设为 3, 即为第 2 ⾏的宽度是第 0 ⾏的 3 倍
layout->setRowStretch(2, 3);
// 设置 layout 到窗⼝中.
this->setLayout(layout);
}
5. QFormLayout——表单布局
QRormLayout表单布局,多用于给手机用户的信息,比如我们在学校里,qq群里会发收集每个人的电话号码的文档,其中这个文档中要输入学号,姓名,和电话,填完之后就可以直接进行提交了。
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 创建 layout
QFormLayout* layout = new QFormLayout();
this->setLayout(layout);
// 创建三个 label
QLabel* label1 = new QLabel("姓名");
QLabel* label2 = new QLabel("学号");
QLabel* label3 = new QLabel("电话");
// 创建三个 lineEdit
QLineEdit* lineEdit1 = new QLineEdit();
QLineEdit* lineEdit2 = new QLineEdit();
QLineEdit* lineEdit3 = new QLineEdit();
// 创建⼀个提交按钮
QPushButton* btn = new QPushButton("提交");
// 把上述元素添加到 layout 中
layout->addRow(label1, lineEdit1);
layout->addRow(label2, lineEdit2);
layout->addRow(label3, lineEdit3);
layout->addRow(NULL, btn);
}
6. QSpacer
上述我们设置的布局中的按钮之间挨着都是比较近的,有的时候我们想要他们之间有些间隔,就可以用到QSapcer
核心属性:
属性 | 说明 |
---|---|
width | 宽度 |
height | 高度 |
hData | 水平方向的 sizePolicy (QSizePolicy::Ignored : 忽略控件的尺寸,不对布局产⽣影响)(QSizePolicy::Minimum :控件的最小尺寸为固定值,布局时不会超过该值。)(QSizePolicy::Maximum : 控件的最大尺寸为固定值,布局时不会小于该值。 )(QSizePolicy::Preferred : 控件的理想尺寸为固定值,布局时会尽量接近该值。)(QSizePolicy::Expanding : 控件的尺寸可以根据空间调整,尽可能占据更多空间。)(QSizePolicy::Shrinking : 控件的尺寸可以根据空间调整,尽可能缩小以适应空间。) |
vData | 垂直方向的 sizePolicy 选项同上. |
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QHBoxLayout* layout = new QHBoxLayout();
this->setLayout(layout);
QPushButton* btn1 = new QPushButton("按钮1");
QPushButton* btn2 = new QPushButton("按钮2");
// 创建Spacer
QSpacerItem* spacer = new QSpacerItem(200, 20);
layout->addWidget(btn1);
// 这个是按照添加的顺序来添加的,放在中间说明放在两个按钮的中间
layout->addSpacerItem(spacer);
layout->addWidget(btn2);
}