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

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


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

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

相关文章

kubenetes中K8S的命名空间状态异常强制删除Terminating的ns

查看ns状态为异常: 查看ns为monitoring的状态为Termingating状态 使用方法一: kubectl delete ns monitoring --force --grace-period0 使用方法二: kubectl get ns monitoring -o json > monitoring.json 修改删除文件中的"kubern…

Redis优化笔记

Redis优化 一:Key: 1.1.Key的规范: 测试如下: 1.2.拒绝BigKey: 我们可以用: MEMORY USAGE name命令来看它的大小。 注意,这里的第二种之所以不使用Keys *,因为在实际生产时&#…

强化学习算法

从上图看出,强化学习可以分成价值/策略、随机策略/确定策略、在线策略/离线策略、蒙特卡洛/时间差分这四个维度。这里分析了基础算法中除了在线策略/离线策略以外的其他维度。 (一)基础知识 一、基础概念 重点概念:状态S、动作A、…

Android:使用Kotlin搭建MVC架构模式

一、简介Android MVC架构模式 M 层 model ,负责处理数据,例如网络请求、数据变化 V 层 对应的是布局 C 层 Controller, 对应的是Activity,处理业务逻辑,包含V层的事情,还会做其他的事情,导致 ac…

切换分支报错:Untracked Files Prevent Checkout

切换分支报错:Untracked Files Prevent Checkout 分支切换 Untracked Files Prevent Checkout 新起的项目在切换master分支到工作分支时,出现下图的问题: Untracked Files Prevent Checkout Move or commit them before checkout 网上的解决…

回溯算法05(leetcode491/46/47)

参考资料: https://programmercarl.com/0491.%E9%80%92%E5%A2%9E%E5%AD%90%E5%BA%8F%E5%88%97.html 491. 非递减子序列 题目描述: 给你一个整数数组 nums ,找出并返回所有该数组中不同的递增子序列,递增子序列中 至少有两个元素…

大数据智慧消防解决方案(24页PPT)

方案介绍: 大数据智慧消防解决方案是提升消防安全管理水平、保障人民群众生命财产安全的重要手段。通过集成物联网、云计算、大数据、人工智能等先进技术,构建集监测、预警、指挥、救援于一体的智慧消防系统,将为消防安全事业注入新的活力。…

工业级3D开发引擎HOOPS:创新与效率的融合!

在当今这个技术日新月异的时代,3D技术已成为推动各行各业发展的重要力量。从工程设计到游戏开发,从虚拟现实到增强现实,3D技术的应用无处不在,它极大地丰富了我们的生活和工作。而在这样的背景下,HOOPS作为一个强大的3…

爬虫技术升级:如何结合DrissionPage和Auth代理插件实现数据采集

背景/引言 在大数据时代,网络爬虫技术已经成为数据收集的重要手段之一。爬虫技术可以自动化地从互联网上收集数据,节省大量人力和时间成本。然而,当使用需要身份验证的代理服务器时,许多现有的爬虫框架并不直接支持代理认证。这就…

测试自动生成目录

目录 1,标题一 2,标题二 3,标题三 4,怎么做到的 1,标题一 内容11111111111111111111 2,标题二 内容22222222222222222 3,标题三 内容3333333333333333333 4,怎么做到的

递增链表去重

题目描述: 题目思路: 1.链表内的val是递增的,所以相同的值只会连续重复地出现。 2.设置三个指针: ①指向头结点指针,用于返回链表 ②指向返回链表链尾的指针,用于在新链表添加结点 ③遍历旧链表结点的…

C++ | Leetcode C++题解之第107题二叉树的层序遍历II

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<vector<int>> levelOrderBottom(TreeNode* root) {auto levelOrder vector<vector<int>>();if (!root) {return levelOrder;}queue<TreeNode*> q;q.push(root);while (!q.e…

Redis实践—全国地址信息缓存

一、背景 在涉及全国地址的应用中&#xff0c;地址信息通常被频繁地查询和使用&#xff0c;例如电商平台、物流系统等。为了提高系统性能和减少对数据库的访问压力&#xff0c;可以使用缓存来存储常用的地址信息&#xff0c;其中 Redis 是一个非常流行的选择。 本次在一个企业入…

Redis的下载、安装、启动和初尝试【超级简单】

redis最好是在Linux系统中使用&#xff0c;这是最接近生产实际的环境。 不过&#xff0c;我们初学者&#xff0c;目的是学习Redis的使用、原理&#xff0c;如果在Linux下直接学习Redis&#xff0c;很可能会因为命令不熟悉而劝退&#xff0c;这是不好的。 因此&#xff0c;我主张…

linux命令中arj使用

arj 用于创建和管理.arj压缩包 补充说明 arj命令 是 .arj 格式的压缩文件的管理器&#xff0c;用于创建和管理 .arj 压缩包。 语法 arj(参数)参数 操作指令&#xff1a;对 .arj 压缩包执行的操作指令&#xff1b;压缩包名称&#xff1a;指定要操作的arj压缩包名称。 更多…

.NET Core Web Api Swagger运行异常

遇到的问题 因为新增了一个控制器方法&#xff0c;从而导致在运行Swagger的时候直接报错&#xff0c;异常如下&#xff1a; SwaggerGeneratorException: Conflicting method/path combination "POST api/UserOperationExample" for actions - WebApi.Controllers.Us…

HTML+CSS+JS 扩散登录表单动画

效果演示 Code <!DOCTYPE html> <html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,us…

光明于心,自理成翼:盲人生活自理能力训练探索

在探索未知的旅途中&#xff0c;盲人朋友同样怀揣着对自由与独立的向往。随着科技的不断进步&#xff0c;一款名为“蝙蝠避障”的辅助软件以其独特的实时避障与拍照识别功能&#xff0c;成为了盲人朋友提升生活自理能力的有力工具。本文将深入探讨盲人生活自理能力训练&#xf…

代码随想录--哈希表--有效的字母异位词

题目 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 示例 1: 输入: s “anagram”, t “nagaram” 输出: true 示例 2: 输入: s “rat”, t “car” 输出: false 说明: 你可以假设字符串只包含小写字母。 思路 先看暴力的解法&am…

低功耗 DC/DC 转换器的复杂设计原理分析介绍

DC/DC 转换解决方案都是低噪声线性设计&#xff0c;易于使用&#xff0c;但有两个主要缺点。首先&#xff0c;输出电压必须始终低于输入电压&#xff1b;然而&#xff0c;线性稳压器的效率非常低&#xff0c;并且将大部分供电功率以热量的形式耗散。其次&#xff0c;根据输入和…