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

【Qt】如何优雅的进行界面布局

文章目录

  • 1 :peach:写在前面:peach:
  • 2 :peach:垂直布局:peach:
  • 3 :peach:水平布局:peach:
  • 4 :peach:网格布局:peach:
  • 5 :peach:表单布局:peach:


1 🍑写在前面🍑

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

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


2 🍑垂直布局🍑

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

核⼼属性:

属性说明
layoutLeftMargin左侧边距
layoutRightMargin右侧边距
layoutTopMargin上⽅边距
layoutBottomMargin下⽅边距
layoutSpacing相邻元素之间的间距

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

代码示例:

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);
}

验证结果:
在这里插入图片描述
使用代码的方式时我们拖拽窗口时,按钮的位置也会随着窗口的调整而改变。

我们还可以使用图形化界面的方式来进行垂直布局:
在这里插入图片描述
但是注意使用图形化界面的方式时我们拖拽窗口,按钮的位置不会随着窗口的调整而改变。


3 🍑水平布局🍑

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

核⼼属性 (和 QVBoxLayout 属性是⼀致的)

属性说明
layoutLeftMargin左侧边距
layoutRightMargin右侧边距
layoutTopMargin上⽅边距
layoutBottomMargin下⽅边距
layoutSpacing相邻元素之间的间距

代码⽰例:

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");// 创建布局管理器QHBoxLayout* layout = new QHBoxLayout();layout->addWidget(btn1);layout->addWidget(btn2);layout->addWidget(btn3);// 设置 layout 到 widget 上this->setLayout(layout);
}

结果验证:
在这里插入图片描述

同理我们也可以使用图形化界面的方式来创建水平布局。这里就不再演示了。


4 🍑网格布局🍑

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

核⼼属性:整体和 QVBoxLayout 以及 QHBoxLayout 相似,但是设置 spacing 的时候是按照垂直⽔平两个⽅向来设置的。

属性说明
layoutLeftMargin左侧边距
layoutRightMargin右侧边距
layoutTopMargin上⽅边距
layoutBottomMargin下⽅边距
layoutHorizontalSpacing相邻元素之间⽔平⽅向的间距
layoutVerticalSpacing相邻元素之间垂直⽅向的间距
layoutRowStretch⾏⽅向的拉伸系数
layoutColumnStretch列⽅向的拉伸系数

代码⽰例:

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 创建 4 个按钮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, 0, 2);layout->addWidget(btn3, 1, 1);layout->addWidget(btn4, 1, 3);// 设置 layout 到窗⼝中.this->setLayout(layout);
}

结果验证:
在这里插入图片描述
我们再来看看使用下面的代码会出现什么情况:

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 创建 4 个按钮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, 0);layout->addWidget(btn3, 2, 0);layout->addWidget(btn4, 5, 0);// 设置 layout 到窗⼝中.this->setLayout(layout);
}

结果验证:
在这里插入图片描述
此处也要注意, 设置⾏和列的时候, 如果设置的是⼀个很⼤的值, 但是这个值和上⼀个值之间并没有其他的元素, 那么并不会在中间腾出额外的空间。

代码⽰例: 设置 QGridLayout 中元素的⼤⼩⽐例

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的话为默认大小// 第 0 列拉伸⽐例设为 3;layout->setColumnStretch(0, 3);// 第 1 列拉伸⽐例设为 2,layout->setColumnStretch(1, 2);// 第 2 列拉伸⽐例设为 1layout->setColumnStretch(2, 1);// 设置 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::Preferred, QSizePolicy::Expanding);btn2->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);btn3->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);btn4->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);btn5->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);btn6->setSizePolicy(QSizePolicy::Preferred, 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 ⾏拉伸⽐例设为 2, 即为第 2 ⾏的宽度是第 0 ⾏的 2 倍layout->setRowStretch(2, 2);// 设置 layout 到窗⼝中.this->setLayout(layout);
}

结果验证:
在这里插入图片描述


5 🍑表单布局🍑

除了上述的布局管理器之外, Qt 还提供了 QFormLayout , 属于是 QGridLayout 的特殊情况, 专⻔⽤于实现两列表单的布局。这种表单布局多⽤于让⽤⼾填写信息的场景,左侧列为提⽰, 右侧列为输⼊框。

代码示例:

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// 创建 layoutQFormLayout* layout = new QFormLayout();this->setLayout(layout);// 创建三个 labelQLabel* label1 = new QLabel("姓名");QLabel* label2 = new QLabel("年龄");QLabel* label3 = new QLabel("电话");// 创建三个 lineEditQLineEdit* 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);}

结果验证:
在这里插入图片描述


相关文章:

【Qt】如何优雅的进行界面布局

文章目录 1 :peach:写在前面:peach:2 :peach:垂直布局:peach:3 :peach:水平布局:peach:4 :peach:网格布局:peach:5 :peach:表单布局:peach: 1 🍑写在前面🍑 之前使⽤ Qt 在界⾯上创建的控件, 都是通过 “绝对定位” 的⽅式来设定的。也就是每个控件所在…...

【八股系列】分别说一下nodeJS和浏览器的事件循环机制?

文章目录 1. NodeJS1.1 Node.js 事件循环概念1.2 Node.js 事件循环工作流程1.3 Node.js 事件循环示例 2. 浏览器2.1 浏览器事件循环概念2.2 浏览器事件循环工作流程2.3 浏览器事件循环示例 1. NodeJS 1.1 Node.js 事件循环概念 在 Node.js 中,事件循环由 libuv 库…...

关于基础的流量分析(1)

1.对于流量分析基本认识 1)简介:网络流量分析是指捕捉网络中流动的数据包,并通过查看包内部数据以及进行相关的协议、流量分析、统计等来发现网络运行过程中出现的问题。 2)在我们平时的考核和CTF比赛中,基本每次都有…...

数据结构---树,二叉树的简单概念介绍、堆和堆排序

树 树的概念和结构 结构 在我们将堆之前,我们先来了解一下我们的树。 我们的堆是属于树里面的一种, 树是一种非线性结构,是一种一对多的一种结构,也就是我们的一个节点可能有多个后继节点,当然也可以只有一个或者没…...

MySQL聚合函数(多行函数)

聚合函数(多行函数) 聚合函数作用于一组数据,并对一组数据返回一个值。 常见聚合函数 AVG和SUM函数 只作用于数值类型数据,不包含NULL 求工资平均值和总和 MIN和MAX函数 可以作用于任何数据类型(如字符串&#xff0c…...

智慧教室课堂-专注度及考试作弊系统、课堂动态点名,情绪识别、表情识别和人脸识别结合

课堂专注度分析: 课堂专注度表情识别 作弊检测: 关键点计算方法 转头(probe)低头(peep)传递物品(passing) 侧面的传递物品识别 逻辑回归关键点 使用: 运行setup.py安装必要内容 python setup.py build develop 运行demo_inference.py 将…...

单例模式简要介绍

学习目标: 单例模式 学习内容: 单例模式(Singleton Pattern)是一种设计模式,其主要目的是确保一个类只有一个实例,并且提供一个全局的访问点。它常用于需要全局唯一对象的场景,例如日志记录器、…...

深度学习面试问题总结(21)| 模型优化

本文给大家带来的百面算法工程师是深度学习模型优化面试总结,文章内总结了常见的提问问题,旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中,我们还将介绍一些常见的深度学习面试问题,并提供参考的回答及其理论基础&a…...

4月手机行业线上市场销售数据分析

政府对智能手机行业的支持政策,如5G推广,以及相关的产业政策,都在一定程度上推动了智能手机市场的发展,再加上AI应用的推广和全球科技迅猛发展,中国手机市场在2024年迎来了恢复性增长。 据鲸参谋数据统计,…...

首都师范大学聘请旅美经济学家向凌云为客座教授

2024年4月17日,首都师范大学客座教授聘任仪式在首都师范大学资源环境与旅游学院举行。首都师范大学资源环境与旅游学院院长吕拉昌主持了仪式,并为旅美经济学家向凌云教授颁发了聘书。 吕拉昌院长指出,要贯彻教育部产学研一体化战略&#xff0…...

多电脑共享鼠标键盘

由于要在两个电脑之间共用一套鼠标键盘,所以在此记录一下。 mouse without borders Mouse without Borders 是一款免费的 Windows 工具,允许你在多台电脑之间共享鼠标和键盘。 安装与配置步骤 下载和安装: 前往 Mouse without Borders 官…...

展厅设计对企业有哪些作用

1、增强品牌形象 企业展厅对于增强企业品牌形象、提升企业的知名度和市场竞争力具有显著作用和意义。展厅作为企业对外的窗口,是客户和访客了解企业的第一印象。通过独特的设计风格和精心的展示布局,企业可以将自身的核心价值和文化理念巧妙地融入到展厅…...

LeetCode-102. 二叉树的层序遍历【树 广度优先搜索 二叉树】

LeetCode-102. 二叉树的层序遍历【树 广度优先搜索 二叉树】 题目描述:解题思路一:一个全局队列queue,while queue:去搜集当前所有queue的level解题思路二:背诵版解题思路三: 题目描述: 给你二…...

基于时频模糊算子的数据增强方法

关键词:时频模糊,数据增强,机器学习,音频预处理 我们引入时频模糊算子,该算子将信号的短时傅里叶变换与指定的核进行卷积,在SpeechCommands V2数据集上训练了一个使用ResNet-34架构的卷积神经网络(CNN)和一…...

浅谈后端整合Springboot框架后操作基础配置

boot基础配置 现在不访问端口8080 可以吗 我们在默认启动的时候访问的是端口号8080 基于属性配置的 现在boot整合导致Tomcat服务器的配置文件没了 我们怎么去修改Tomcat服务器的配置信息呢 配置文件中的配置信息是很多很多的... 复制工程 保留工程的基础结构 抹掉原始…...

英码科技算能系列边缘计算盒子再添新成员!搭载TPU处理器BM1688CV186AH,功耗更低、接口更丰富

在数据呈现指数级增长的今天,越来越多的领域和细分场景对实时、高效的数据处理和分析的需求日益增长,对智能算力的需求也不断增强。为应对新的市场趋势,英码科技凭借自身的硬件研发优势,携手算能相继推出了基于BM1684的边缘计算盒…...

selenium 爬取今日头条

由于今日头条网页是动态渲染,再加上各种token再验证,因此直接通过API接口获取数据难度很大,本文使用selenium来实现新闻内容爬取。 selenium核心代码 知识点: 代码中加了很多的异常处理,保证错误后重试,…...

docker 安装 yapi

文章目录 docker 安装 yapi一、拉取镜像二、创建目录三、添加配置文件四、初始化数据库表五、启动 yapi六、测试以及修改默认密码 没有 MongDB 的可以先看这个教程:MongDB安装教程 docker 安装 yapi 版本: 1.9.5 一、拉取镜像 docker pull yapipro/y…...

【AI如何帮你编写测试用例并输出表格格式】

1、工具:顺便使用一款生成式AI即可,此处用的是ChatGPT,Kimi这两个工具试验。 2、首先要拿到需求文档,根据需求文档向AI发出如下指令(Prompt) “请根据下面这段需求,编写测试用例: …...

九宫格转圈圈抽奖活动,有加速,减速效果

在线访问demo和代码在底部 代码&#xff0c;复制就可以跑 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><tit…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

VB.net复制Ntag213卡写入UID

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?ftt&id615391857885 一、读取旧Ntag卡的UID和数据 Private Sub Button15_Click(sender As Object, e As EventArgs) Handles Button15.Click轻松读卡技术支持:网站:Dim i, j As IntegerDim cardidhex, …...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

人机融合智能 | “人智交互”跨学科新领域

本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

基于Springboot+Vue的办公管理系统

角色&#xff1a; 管理员、员工 技术&#xff1a; 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能&#xff1a; 该办公管理系统是一个综合性的企业内部管理平台&#xff0c;旨在提升企业运营效率和员工管理水…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

python打卡第47天

昨天代码中注意力热图的部分顺移至今天 知识点回顾&#xff1a; 热力图 作业&#xff1a;对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图&#xff0c;展示模…...

【技巧】dify前端源代码修改第一弹-增加tab页

回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码&#xff0c;在知识库增加一个tab页"HELLO WORLD"&#xff0c;完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...