Qt:布局管理器Layout

目录

布局管理器

QVBoxLayout

QHBoxLayout

QGirdLayout

QFormLayout

Spacer


布局管理器

在以往的界面操作上,都是程序员手动拖动控件来布局,这种方式有一些不足之处,比如不能很好的把握控件之间的距离,以及控件的大小,并且在最终的窗口中,改变窗口大小时,控件的大小不能很好的适应。

于是,引入布局管理器,它是一种控件,可以自动管理其他控件。

常见的布局管理器有垂直布局管理器、水平布局管理器、网格布局、表单布局。

QVBoxLayout

布局管理器只用于界面布局,不提供信号。

cpp 复制代码
Widget::Widget(QWidget *parent)
 : QWidget(parent)
 , ui(new Ui::Widget)
{
 ui->setupUi(this);
 // 创建三个按钮
 QPushButton* btn1 = new QPushButton("按钮1");
 QPushButton* btn2 = new QPushButton("按钮2");
 QPushButton* btn3 = new QPushButton("按钮3");

 // 创建布局管理器, 并且把按钮添加进去
 // 如果创建的时候指定⽗元素为 this, 则后⾯不需要 setLayout ⽅法了.
 QVBoxLayout* layout = new QVBoxLayout();
 layout->addWidget(btn1);
 layout->addWidget(btn2);
 layout->addWidget(btn3);

 // 把布局管理器设置到 widget 中
 this->setLayout(layout);
}

每个Widget只能设置一个布局管理器。

使用Qt Design创建两个布局管理器

程序运行后,界面可以正常显示。但是,这两个布局管理器并不会适应窗口的大小变化,因为本质上这是两个Widget。

QHBoxLayout

垂直布局中可以嵌套一个水平布局,反过来也可以。

QGirdLayout

网格布局,可以实现M * N的效果。

cpp 复制代码
 QPushButton* btn1 = new QPushButton("按钮1");
 QPushButton* btn2 = new QPushButton("按钮2");
 QPushButton* btn3 = new QPushButton("按钮3");
 QPushButton* btn4 = new QPushButton("按钮4");

 QGridLayout* layout = new QGridLayout();
 layout->addWidget(btn1, 0, 0);
 layout->addWidget(btn2, 1, 1);
 layout->addWidget(btn3, 2, 2);
 layout->addWidget(btn4, 3, 3);

this->setLayout(layout);
  • 设置水平方向的拉伸系数
cpp 复制代码
// 创建 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);
  • 设置垂直方向的拉伸系数
cpp 复制代码
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);
 }

什么是SizePolicy

在界面中,每个按钮的高度是固定,即使布局管理器按照比例设置了拉伸系数,也是没有效果的,而想让设置生效,就要设置每个按钮的SizePolicy,按钮的尺寸策略有如下几种。
使⽤ setSizePolicy 设置按钮的尺⼨策略. 可选的值如下:
QSizePolicy::Ignored : 忽略控件的尺⼨,不对布局产⽣影响。
QSizePolicy::Minimum : 控件的最⼩尺⼨为固定值,布局时不会超过该值。
QSizePolicy::Maximum : 控件的最⼤尺⼨为固定值,布局时不会⼩于该值。
QSizePolicy::Preferred : 控件的理想尺⼨为固定值,布局时会尽量接近该值。
QSizePolicy::Expanding : 控件的尺⼨可以根据空间调整,尽可能占据更多空间。
QSizePolicy::Shrinking : 控件的尺⼨可以根据空间调整,尽可能缩⼩以适应空间。

总的来说, 使⽤ QGridLayout 能够代替很多 QHBoxLayout 和 QVBoxLayout 嵌套的场景. 毕
竟嵌套的代码写起来是⽐较⿇烦的.
另外不要忘了, QGridLayout ⾥⾯也能嵌套 QHBoxLayout 和 QVBoxLayout , QHBoxLayout 和 QVBoxLayout ⾥⾯也能嵌套 QGridLayout 。 灵活使⽤上述布局管理器, 就可以实现出任意的复杂界⾯。

QFormLayout

表单布局,N行2列,主要用于填表这样的场景。

cpp 复制代码
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);
}

Spacer

Spacer不属于布局管理器,往往搭配在布局管理器中使用,表示一个空白块,可以用来让两个控件之间的距离变大。

  • 属性
cpp 复制代码
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);
 // 在两个 widget 中间添加空⽩
 layout->addSpacerItem(spacer);
 layout->addWidget(btn2);
 }
相关推荐
君莫笑几人回6 分钟前
关于记录一下“bug”,在做图片上传的时候出现的小问题
java·开发语言·spring boot
技术不支持10 分钟前
Qt Creator 11.0.3 语法高亮bug问题
java·服务器·数据库·qt·bug
Hello小赵22 分钟前
嵌入式硬件学习(十)—— LED驱动+杂项设备驱动
嵌入式硬件·学习
R-G-B27 分钟前
【08】C++实战篇——C++ 生成动态库.dll 及 C++调用DLL,及实际项目中的使用技巧
c++·c++ 生成动态库.dll·c++ 生成静态库.lib·c++调用动态库.dll·c++调用静态库.lib·c++调用dll·c++调用lib
rockmelodies32 分钟前
RSA 解密逻辑
开发语言·python
CC呢1 小时前
基于单片机一氧化碳CO检测/煤气防中毒检测报警系统
单片机·嵌入式硬件·一氧化碳检测
澡点睡觉1 小时前
golang的包和闭包
开发语言·后端·golang
止观止1 小时前
Remix框架:高性能React全栈开发实战
前端·react.js·前端框架·remix
Dxy12393102162 小时前
python创建一个excel文件
开发语言·python·excel
朝朝又沐沐2 小时前
算法竞赛阶段二-数据结构(40)数据结构栈的STL
开发语言·数据结构·c++·算法