【QT】布局管理器

news2024/11/16 16:46:26

布局管理器

  • 布局管理器
    • 1. 垂直布局
    • 2. 水平布局
    • 3. 网格布局
    • 4. 表单布局
    • 5. Spacer

布局管理器

之前使⽤ Qt 在界⾯上创建的控件, 都是通过 “绝对定位” 的⽅式来设定的;也就是每个控件所在的位置, 都需要计算坐标, 最终通过 setGeometry 或者 move ⽅式摆放过去。

这种设定⽅式其实并不⽅便. 尤其是界⾯如果内容⽐较多, 不好计算. ⽽且⼀个窗⼝⼤⼩往往是可以调整的, 按照绝对定位的⽅式, 也⽆法⾃适应窗⼝⼤⼩。因此 Qt 引⼊ “布局管理器” (Layout) 机制, 来解决上述问题。

1. 垂直布局

使⽤ QVBoxLayout 表示垂直的布局管理器。V 是 vertical 的缩写。

核心属性:

在这里插入图片描述

Layout 只是⽤于界⾯布局, 并没有提供信号。

代码示例:使用 QVBoxLayout 管理多个控件.

1)编写代码, 创建布局管理器和三个按钮. 并且把按钮添加到布局管理器中.

  • 使⽤ addWidget 把控件添加到布局管理器中.

  • 使⽤ setLayout 设置该布局管理器到 widget 中.

      		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");
      		
      		    // 创建布局管理器,并且把按钮添加进去
      		    // 如果创建的时候指定父元素为 this,则后面不需要 setLayout 方法了
      		    QVBoxLayout* layout = new QVBoxLayout();
      		    layout->addWidget(button1);
      		    layout->addWidget(button2);
      		    layout->addWidget(button3);
      		
      		    // 把布局管理器设置到 widget 中
      		    this->setLayout(layout);
      		}
    

通过上述代码的⽅式, 只能给这个 widget 设定⼀个布局管理器. 实际上也可以通过 Qt Design 在⼀个窗⼝中创建多个布局管理器。

代码示例2:创建两个 QVBoxLayout

1)在界⾯上创建两个 QVBoxLayout , 每个 QVBoxLayout 各放三个按钮.

点击如下红框创建 QVBoxLayout:

在这里插入图片描述

2)运⾏程序, 可以看到这些按钮已经⾃动排列好. 只不过当前这些按钮的位置不能随着窗⼝⼤⼩⾃动变化.

2. 水平布局

使⽤ QHBoxLayout 表⽰垂直的布局管理器. H 是 horizontal 的缩写.

核心属性 (和 QVBoxLayout 属性是⼀致的):

在这里插入图片描述

代码示例:使用 QHBoxLayout 管理控件

1)编写代码, 创建布局管理器和三个按钮. 并且把按钮添加到布局管理器中.

			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();
			    layout->addWidget(button1);
			    layout->addWidget(button2);
			    layout->addWidget(button3);
			
			    // 设置 layout 到 widget 上
			    this->setLayout(layout);
			}

代码示例2:嵌套的 layout

1)在代码中创建以下内容

使⽤ addLayout 给 layout 中添加⼦ layout.

			Widget::Widget(QWidget *parent)
			    : QWidget(parent)
			    , ui(new Ui::Widget)
			{
			    ui->setupUi(this);
			
			    // 创建顶层 layout
			    QVBoxLayout* layoutParent = new QVBoxLayout();
			    this->setLayout(layoutParent);
			
			    // 添加两个按钮进去
			    QPushButton* button1 = new QPushButton("按钮1");
			    QPushButton* button2 = new QPushButton("按钮2");
			    layoutParent->addWidget(button1);
			    layoutParent->addWidget(button2);
			
			    // 创建子 layout
			    QHBoxLayout* layoutChild = new QHBoxLayout();
			
			    // 添加两个按钮进去
			    QPushButton* button3 = new QPushButton("按钮3");
			    QPushButton* button4 = new QPushButton("按钮4");
			    layoutChild->addWidget(button3);
			    layoutChild->addWidget(button4);
			
			    // 把子 layout 添加到父 layout 中
			    layoutParent->addLayout(layoutChild);
			}

在这里插入图片描述

3. 网格布局

Qt 中还提供了 QGridLayout ⽤来实现⽹格布局的效果. 可以达到 M * N 的这种⽹格的效果.

核心属性:

整体和 QVBoxLayout 以及 QHBoxLayout 相似. 但是设置 spacing 的时候是按照垂直⽔平两个⽅向来设置的.

在这里插入图片描述

代码示例:使⽤ QGridLayout 管理元素

1)代码中创建 QGridLayout 和 4 个按钮.

使⽤ addWidget 添加控件到布局管理器中. 但是添加的同时会指定两个坐标. 表⽰放在第⼏⾏, 第⼏列.

			Widget::Widget(QWidget *parent)
			    : QWidget(parent)
			    , ui(new Ui::Widget)
			{
			    ui->setupUi(this);
			    // 创建 4 个按钮
			    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, 0, 1);
			    layout->addWidget(button3, 1, 0);
			    layout->addWidget(button4, 1, 1);
			
			    // 设置 layout 到窗口中
			    this->setLayout(layout);
			}
  1. 执⾏代码, 观察效果. 可以看到当前的这⼏个按钮是按照 2 ⾏ 2 列的⽅式排列的.

在这里插入图片描述

代码示例: 设置 QGridLayout 中元素的大小比例

1)创建 6 个按钮, 按照 2 ⾏ 3 列的⽅式排列

  • 使用 setColumnStretch 设置每⼀列的拉伸系数

      		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);
      		
      		    // 设置拉伸比例
      		    // 第 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);
      		}
    

代码示例2:设置垂直⽅向的拉伸系数

1)编写代码, 创建 6 个按钮, 按照 3 ⾏ 2 列⽅式排列.

使⽤ 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);
      		
      		    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");
      		
      		    // 设置按钮的 sizePolicy,此时按钮的水平方向和垂直方向都会尽量舒展开
      		    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);
      		
      		    // 设置拉伸比例
      		    // 第 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);
      		}
    

2)执⾏代码, 观察效果.

此时的按钮垂直⽅向都舒展开了. 并且调整窗⼝尺⼨, 也会按照设定的⽐例同步变化.

在这里插入图片描述

总的来说, 使⽤ QGridLayout 能够代替很多 QHBoxLayout 和 QVBoxLayout 嵌套的场景. 毕竟嵌套的代码写起来是⽐较麻烦的。

另外不要忘了, QGridLayout ⾥⾯也能嵌套 QHBoxLayout 和 QVBoxLayout ,QHBoxLayout 和 QVBoxLayout ⾥⾯也能嵌套 QGridLayout;灵活使⽤上述布局管理器, 就可以实现出任意的复杂界⾯。

4. 表单布局

除了上述的布局管理器之外, Qt 还提供了 QFormLayout , 属于是 QGridLayout 的特殊情况, 专⻔⽤于实现两列表单的布局.

这种表单布局多⽤于让⽤⼾填写信息的场景. 左侧列为提⽰, 右侧列为输⼊框.

代码示例:使⽤ QFormLayout 创建表单.

1)编写代码, 创建 QFormLayout , 以及三个 label 和三个 lineEdit

  • 使⽤ addRow ⽅法来添加⼀⾏. 每⾏包含两个控件. 第⼀个控件固定是 QLabel / ⽂本, 第⼆个控件则可以是任意控件.

  • 如果把第⼀个参数填写为 NULL, 则什么都不显⽰.

      		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* button = new QPushButton("提交");
      		
      		    // 把上述元素添加到 layout 中
      		    layout->addRow(label1, lineEdit1);
      		    layout->addRow(label2, lineEdit2);
      		    layout->addRow(label3, lineEdit3);
      		    layout->addRow(NULL, button);
      		}
    

5. Spacer

使用布局管理器的时候, 可能需要在控件之间, 添加⼀段空白. 就可以使用 QSpacerItem 来表示.

核心属性:

在这里插入图片描述

上述属性在构造函数设置即可.

代码示例:创建⼀组左右排列的按钮.

1)在界⾯上创建⼀个 QVBoxLayout , 并添加两个按钮.

			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");
			
			    layout->addWidget(button1);
			    layout->addWidget(button2);
			}

2)直接运⾏程序, 可以看到两个按钮是紧挨着的

在这里插入图片描述

3)在两个按钮中间添加⼀个 spacer

			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);
			
			    // 在两个 widget 中间添加空白
			    layout->addSpacerItem(spacer);
			
			    layout->addWidget(button2);
			}

4)运⾏程序, 观察代码效果. 可以看到两个按钮之间已经存在了间隔了.

调整 QSpacerItem 不同的尺⼨, 即可看到不同的间距。

在这里插入图片描述

在 Qt Designer 中, 也可以直接给界⾯上添加 spacer:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1923448.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文彻底学会Vue3路由:全面讲解路由流程、路由模式、传参等——全栈开发之路--前端篇(7)路由详解

全栈开发一条龙——前端篇 第一篇:框架确定、ide设置与项目创建 第二篇:介绍项目文件意义、组件结构与导入以及setup的引入。 第三篇:setup语法,设置响应式数据。 第四篇:数据绑定、计算属性和watch监视 第五篇 : 组件…

pytorch-pytorch之LSTM

目录 1. nn.LSTM2. nn.LSTMCell 1. nn.LSTM 初始化函数输入参数与RNN相同,分别是input_size,hidden_size和num_layer foward函数也与RNN类似,只不过返回值除了out外,ht变为(ht,ct) 代码见下图: 2. nn.LSTMCell 初…

SQL优化-索引

什么是索引? 索引( index )是帮助 MySQL 高效获取数据的数据结构 ( 有序 ) 。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据, 这…

这是我见过最棒的大模型干货!!!

大模型技术的发展和迭代2024年已经可以按天来计算了,几乎每天都有新的大模型和技术登场。 从基座模型Mamba2,Jamaba,到Dora,LoftQ,GaLore等最新的微调技术;KTO,IPO,SimPO等微调技术…

STM32实战篇:按键(外部输入信号)触发中断

功能要求 将两个按键分别与引脚PA0、PA1相连接,通过按键按下,能够触发中断响应程序(不需明确功能)。 代码流程如下: 实现代码 #include "stm32f10x.h" // Device headerint main() {//开…

ZGC的流程图

GC标记过程 1、初始标记 扫描所有线程栈的根节点,然后再扫描根节点直接引用的对象并进行标记。这个阶段需要停顿所有的应用线程(STW),但由于只扫描根对象直接引用的对象,所以停顿时间很短。停顿时间高度依赖根节点的数…

鸿蒙HarmonyOS应用开发为何选择ArkTS不是Java?

前言 随着智能设备的快速发展,操作系统的需求也变得越来越多样化。为了满足不同设备的需求,华为推出了鸿蒙HarmonyOS。 与传统的操作系统不同,HarmonyOS采用了一种新的开发语言——ArkTS。 但是,刚推出鸿蒙系统的时候&#xff0…

uni-app 保存号码到通讯录

1、 添加模块 2、添加权限 3、添加策略 Android: "permissionExternalStorage" : {"request" : "none","prompt" : "应用保存运行状态等信息,需要获取读写手机存储(系统提示为访问设备上的照片…

Prometheus + alermanager + webhook-dingtalk 告警

添加钉钉机器人 1. 部署 alermanager 1.1 下载软件包 wget https://github.com/prometheus/alertmanager/releases/download/v0.26.0/alertmanager-0.26.0.linux-amd64.tar.gz 网址 :Releases prometheus/alertmanager (github.com) 1.2 解压软件包 mkdir -pv …

用 Kotlin 编写四则运算计算器:从零开始的简单教程

人不走空 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌赋:斯是陋室,惟吾德馨 目录 🌈个人主页:人不走空 💖系列专栏:算法专题 ⏰诗词歌…

电-气阀门定位器YT-1000系列产品说明

电-气阀门定位器YT-1000系列 使用注意事项 • 搬运安装或使用中对产品过大的震动或撞击会成为产品故障的原因。 • 超过规定参数范围使用也会成为产品故陷的原因。 • 不使用的气路接口要用堵塞堵住。 • 不使用产品而长时间放悝在室外时,要盖上产品外壳以免雨水进入产品…

八款主流电脑监控软件推荐|2024年最佳电脑监控软件排行榜

在现代社会中,电脑监控软件已经成为企业和家庭不可或缺的工具。无论是为了确保员工的工作效率,还是保护孩子在互联网上的安全,这些软件都能提供有力的支持。本文将为大家介绍2024年最受欢迎的八款电脑监控软件。 1. 固信软件 固信软件是一款综…

服务重启时容器未自动启动

1、容器重启策略 通过设置容器的重启策略,‌可以决定在容器退出时Docker守护进程是否重启该容器。‌常见的重启策略包括:‌ no:‌不重启容器,‌默认策略。‌always:‌无论容器是如何退出的,‌总是重启容器…

2024年公共文化与社会服务国际会议(ICPCSS 2024)

2024年公共文化与社会服务国际会议 2024 International Conference on Public Culture and Social Services 【1】会议简介 2024年公共文化与社会服务国际会议是一个集学术性、实践性和国际性于一体的盛会。我们期待与您共同探讨公共文化与社会服务的未来发展方向,为…

【公益案例展】华为云X《无尽攀登》——攀登不停,向上而行

‍ 华为云公益案例 本项目案例由华为云投递并参与数据猿与上海大数据联盟联合推出的 #榜样的力量# 《2024中国数据智能产业最具社会责任感企业》榜单/奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 夏伯渝,中国无腿登珠峰第一人,一生43年…

基于GIS矿产勘查靶区优选技术

定义: 找矿远景区(ore-finding prospect): 一般将中小比例尺(小于等于1:10万)成矿预测所圈定的找矿有利地段(preferable ore-finding area)成为找矿远景区 找矿靶区(ore-finding t…

IPD流程学习笔记

一、前言 互联网行业讲究的是快速试错,所以IPD流程的应用并不多,但是传统企业数字化转型中,怎么确保项目投入可以切合市场需求,有较好的ROI及落地性,轻量级的IPD还是很有必要了解下的,特别是重资产类的业务…

LAMP万字详解(概念、构建步骤)

目录 LAMP Apache 起源 主要特点 软件版本 编译安装httpd服务器 编译安装的优点 操作步骤 准备工作 编译 安装 优化执行路径 添加服务 守护进程 配置httpd 查看 Web 站点的访问情况 虚拟主机 类型 部署基于域名的虚拟主机 为虚拟主机提供域名解析&#xff…

原料药合成偶联反应中钯残留去除

摘要:海普开发的HP214 是一种具有螯合硫脲基团的大孔树脂,专为选择性去除汞、铂族贵金属、金和银而设计。同时还特别适用于从有机工艺流程中回收钯催化剂。 #原料药合成偶联反应中钯残留去除 在有机合成中,以过渡金属络合物催化进行高选择性…

博士论文 | 神经网络的结构与表示 147页

由于神经网络在人工智能领域占据主导地位,一个试图了解其内部工作原理的研究分支领域应运而生。这个子领域的一个标准方法是将神经网络主要理解为代表人类可理解的特征。另一种探索较少的可能性是将它们理解为多步骤的计算机程序。这样做的一个先决条件似乎是某种形…