当前位置: 首页 > news >正文

Qt——布局管理器(一)

1.目前GUI开发方式:绝对定位

直接在像素级指定各个组件的位置和大小,但是组建的位置和大小无法自适应父窗口的变化

解决方案:布局管理器,提供相关的类对界面组件进行布局管理

  • 能够自动排列窗口中的界面组件
  • 窗口变化后自动更新界面组件的大小

2.QLayout是Qt中布局管理器的抽象基类

(1)QBoxLayout布局管理器:以水平或垂直的方式管理界面组件

原来的代码:

Widget::Widget(QWidget *parent) : QWidget(parent), TestBtn1(this), TestBtn2(this), TestBtn3(this), TestBtn4(this) { initControl(); } void Widget::initControl() { TestBtn1.setText("TestBtn1"); TestBtn1.move(20, 20); TestBtn1.resize(160, 30); TestBtn2.setText("TestBtn2"); TestBtn2.move(20, 70); TestBtn2.resize(160, 30); TestBtn3.setText("TestBtn3"); TestBtn3.move(20, 120); TestBtn3.resize(160, 30); TestBtn4.setText("TestBtn4"); TestBtn4.move(20, 170); TestBtn4.resize(160, 30); } Widget::~Widget() { }

使用QBoxLayout后的代码:

Widget::Widget(QWidget *parent) : QWidget(parent), TestBtn1(this), TestBtn2(this), TestBtn3(this), TestBtn4(this) { testVBoxLayout(); } void Widget::testVBoxLayout() { QVBoxLayout* layout = new QVBoxLayout(); TestBtn1.setText("TestBtn1"); TestBtn2.setText("TestBtn2"); TestBtn3.setText("TestBtn3"); TestBtn4.setText("TestBtn4"); layout->addWidget(&TestBtn1); layout->addWidget(&TestBtn2); layout->addWidget(&TestBtn3); layout->addWidget(&TestBtn4); setLayout(layout); } Widget::~Widget() { }

但是该布局策略为:随着窗口放大,按钮的高度不变,只有宽度放大,如何改变呢?

Widget::Widget(QWidget *parent) : QWidget(parent), TestBtn1(this), TestBtn2(this), TestBtn3(this), TestBtn4(this) { testHBoxLayout(); } void Widget::testVBoxLayout() //垂直布局 { QVBoxLayout* layout = new QVBoxLayout(); TestBtn1.setText("TestBtn1"); //让按钮 TestBtn1 在水平和垂直两个方向上,都自动拉伸填满父布局的可用空间。 TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn1.setMinimumSize(160,30); //设置按钮最小长度和高度 TestBtn2.setText("TestBtn2"); TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn2.setMinimumSize(160,30); TestBtn3.setText("TestBtn3"); TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn3.setMinimumSize(160,30); TestBtn4.setText("TestBtn4"); TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn4.setMinimumSize(160,30); layout->setSpacing(30); //设置按钮之间的距离 layout->addWidget(&TestBtn1); layout->addWidget(&TestBtn2); layout->addWidget(&TestBtn3); layout->addWidget(&TestBtn4); setLayout(layout); } void Widget::testHBoxLayout() //水平布局 { QHBoxLayout* layout = new QHBoxLayout(); TestBtn1.setText("TestBtn1"); //让按钮 TestBtn1 在水平和垂直两个方向上,都自动拉伸填满父布局的可用空间。 TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn1.setMinimumSize(160,30); //设置按钮最小长度和高度 TestBtn2.setText("TestBtn2"); TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn2.setMinimumSize(160,30); TestBtn3.setText("TestBtn3"); TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn3.setMinimumSize(160,30); TestBtn4.setText("TestBtn4"); TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn4.setMinimumSize(160,30); layout->setSpacing(30); //设置按钮之间的距离 layout->addWidget(&TestBtn1); layout->addWidget(&TestBtn2); layout->addWidget(&TestBtn3); layout->addWidget(&TestBtn4); setLayout(layout); }

3.布局管理器可以相互嵌套,形成更加复杂的布局方式

void Widget::testVHBoxLayout() //嵌套布局 { QHBoxLayout* hlayout1 = new QHBoxLayout(); QHBoxLayout* hlayout2 = new QHBoxLayout(); QVBoxLayout* vlayout = new QVBoxLayout(); TestBtn1.setText("TestBtn1"); //让按钮 TestBtn1 在水平和垂直两个方向上,都自动拉伸填满父布局的可用空间。 TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn1.setMinimumSize(160,30); //设置按钮最小长度和高度 TestBtn2.setText("TestBtn2"); TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn2.setMinimumSize(160,30); hlayout1->setSpacing(10); hlayout1->addWidget(&TestBtn1); hlayout1->addWidget(&TestBtn2); TestBtn3.setText("TestBtn3"); TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn3.setMinimumSize(160,30); TestBtn4.setText("TestBtn4"); TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn4.setMinimumSize(160,30); hlayout2->setSpacing(10); hlayout2->addWidget(&TestBtn3); hlayout2->addWidget(&TestBtn4); vlayout->setSpacing(10); //设置按钮之间的距离 vlayout->addLayout(hlayout1); vlayout->addLayout(hlayout2); setLayout(vlayout); }

4.布局管理器中的比例系数

  • 默认情况下以等比例的方式更新组件的大小
  • 可以自定义组件大小更新时的比例系数
void Widget::testVBoxLayout() { QVBoxLayout* layout = new QVBoxLayout(); TestBtn1.setText("TestBtn1"); //让按钮 TestBtn1 在水平和垂直两个方向上,都自动拉伸填满父布局的可用空间。 TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn1.setMinimumSize(160,30); //设置按钮最小长度和高度 TestBtn2.setText("TestBtn2"); TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn2.setMinimumSize(160,30); TestBtn3.setText("TestBtn3"); TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn3.setMinimumSize(160,30); TestBtn4.setText("TestBtn4"); TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn4.setMinimumSize(160,30); layout->setSpacing(30); //设置按钮之间的距离 layout->addWidget(&TestBtn1); layout->addWidget(&TestBtn2); layout->addWidget(&TestBtn3); layout->addWidget(&TestBtn4); layout->setStretch(0, 1); //定义第0个格子的比例系数是1 layout->setStretch(1, 1); layout->setStretch(2, 2); layout->setStretch(3, 2); setLayout(layout); } void Widget::testHBoxLayout() { QHBoxLayout* layout = new QHBoxLayout(); TestBtn1.setText("TestBtn1"); //让按钮 TestBtn1 在水平和垂直两个方向上,都自动拉伸填满父布局的可用空间。 TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn1.setMinimumSize(160,30); //设置按钮最小长度和高度 TestBtn2.setText("TestBtn2"); TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn2.setMinimumSize(160,30); TestBtn3.setText("TestBtn3"); TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn3.setMinimumSize(160,30); TestBtn4.setText("TestBtn4"); TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn4.setMinimumSize(160,30); layout->setSpacing(30); //设置按钮之间的距离 layout->addWidget(&TestBtn1); layout->addWidget(&TestBtn2); layout->addWidget(&TestBtn3); layout->addWidget(&TestBtn4); layout->setStretchFactor(&TestBtn1, 1); //将TestBtn1设置系数为1 layout->setStretchFactor(&TestBtn2, 2); layout->setStretchFactor(&TestBtn3, 1); layout->setStretchFactor(&TestBtn4, 3); setLayout(layout); }

注意:组件的初始大小是独立于布局管理器设置的,因此不能保证组件的大小始终符合比例系数的设置,例如上述代码中设置了按钮的初始大小,所以一开始的时候,比例对应不是设置的系数

5.QGridLayout布局管理器,以网格(二维矩阵)的方式管理界面组件

void Widget::testGridLayout1() { QGridLayout* layout = new QGridLayout(); TestBtn1.setText("TestBtn1"); //让按钮 TestBtn1 在水平和垂直两个方向上,都自动拉伸填满父布局的可用空间。 TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn1.setMinimumSize(160,30); //设置按钮最小长度和高度 TestBtn2.setText("TestBtn2"); TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn2.setMinimumSize(160,30); TestBtn3.setText("TestBtn3"); TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn3.setMinimumSize(160,30); TestBtn4.setText("TestBtn4"); TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn4.setMinimumSize(160,30); layout->setSpacing(10); layout->addWidget(&TestBtn1, 0, 0); //将TestBtn1按钮放在(0,0)位置 layout->addWidget(&TestBtn2, 0, 1); layout->addWidget(&TestBtn3, 1, 0); layout->addWidget(&TestBtn4, 1, 1); layout->setRowStretch(0, 1); //设置第0行的比例因子为1 layout->setRowStretch(1, 3); layout->setColumnStretch(0, 1); //设置第0列的比例因子为1 layout->setColumnStretch(1, 3); setLayout(layout); } void Widget::testGridLayout2() { QGridLayout* layout = new QGridLayout(); TestBtn1.setText("TestBtn1"); //让按钮 TestBtn1 在水平和垂直两个方向上,都自动拉伸填满父布局的可用空间。 TestBtn1.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn1.setMinimumSize(160,30); //设置按钮最小长度和高度 TestBtn2.setText("TestBtn2"); TestBtn2.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn2.setMinimumSize(160,30); TestBtn3.setText("TestBtn3"); TestBtn3.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn3.setMinimumSize(160,30); TestBtn4.setText("TestBtn4"); TestBtn4.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); TestBtn4.setMinimumSize(160,30); layout->setSpacing(10); layout->addWidget(&TestBtn1, 0, 0, 2, 1); //将TestBtn1按钮放在(0,0)位置,并且占用2行1列 layout->addWidget(&TestBtn2, 0, 1, 2, 1); layout->addWidget(&TestBtn3, 2, 0, 1, 2); layout->addWidget(&TestBtn4, 3, 0, 1, 2); \ setLayout(layout); }
http://www.jsqmd.com/news/632228/

相关文章:

  • 别再乱重启了!Proxmox集群故障时,先学会用这四条命令精准定位问题
  • DotNetPy:现代.NET 与 Python 互操作 实战指南谏
  • 全国GEO优化服务选择与行业分析指南
  • c++中的模板
  • 2026自吸磁力泵技术解析:防腐化工泵/防腐磁力泵/不锈钢化工泵/不锈钢磁力泵/安徽化工泵/安徽磁力泵/氟合金磁力泵/选择指南 - 优质品牌商家
  • TCP/IP协议详解:高性能服务器开发的底层基石寻
  • 新手入门音响控台培训调音台培训专业迈达斯培训怎么选
  • 单调队列优化多重背包 学习笔记 详解曝
  • 自动导引车(AGV)与自主移动机器人(AMR)控制系统的 C# 开源封装库诠
  • 非线性信号的时间尺度调整
  • 【大模型工程化监控黄金法则】:20年SRE专家亲授5类告警阈值设定铁律,避开97%的误报陷阱
  • 记录复现多模态大模型论文OPERA的一周工作()碳
  • MySQL锁机制:从全局锁到行级锁的深度解读赡
  • Gerrit代码Review高效协作指南:如何利用Topic和CI加速团队开发
  • AI时代,.NET开发者的生存危机还是能力外挂?馅
  • Java与PHP结合的优势第二篇章
  • 工业物联网实时分析的“秒级”革命:拆解DolphinDB如何攻克海量数据下的预警与决策难题腿
  • Z-Image-Turbo部署全攻略:从零开始,快速搭建个人AI绘画站
  • 探秘Cuk升降压电路:如何实现低纹波与高隔离的电源设计
  • 协程执行顺序与作用域解析
  • testserver.cc测试例子解读
  • 手把手教你解决PyTorch的nn、optim模块导入失败:从环境配置到文件命名的避坑全指南
  • 嵌入式无锁任务队列:裸机与RTOS下的零内存分配串行化方案
  • SITS2026多语言支持白皮书核心解密(覆盖197种语言的Tokenization重构工程)
  • MelonLoader完整教程:5分钟学会Unity游戏模组加载终极方案
  • ESP32/ESP8266轻量Toggl时间条目API客户端
  • qemu虚拟机复制
  • 【GUI-Agent】阶跃星辰 GUI-MCP 解读---()---执行层链
  • 告别阻塞!用 PHP TrueAsync 实现 PHP 脚本提速 倍矢
  • Rails 7中的表单验证与错误处理