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

news2024/11/13 10:33:18

文章目录

  • 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 列拉伸⽐例设为 1
    layout->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);

    // 创建 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);

}

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


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

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

相关文章

ElasticSearch IK分词器的安装、词典扩展与停用

🏷️个人主页:牵着猫散步的鼠鼠 🏷️系列专栏:云原生与服务部署-专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 目录 ​编辑 1. 前言 2. IK分词器安装 3. IK分词器词典扩展与停用 4. 总…

基于Python flask的豆瓣电影数据分析可视化系统,功能多,LSTM算法+注意力机制实现情感分析,准确率高达85%

研究背景 随着数字化时代的到来,电影产业正迎来新的发展机遇和挑战。基于Python Flask的豆瓣电影数据分析可视化系统的研究背景凸显了对电影数据的深度分析和情感挖掘的需求。该系统功能丰富,不仅实现了多样化的数据分析功能,还结合了LSTM算…

算法2:滑动窗口(上)

文章目录 长度最小子数组无重复字符的最长子串[最大连续 1 的个数III](https://leetcode.cn/problems/max-consecutive-ones-iii/description/)将x减到0的最小操作数 长度最小子数组 class Solution { public:int minSubArrayLen(int target, vector<int>& nums) {in…

线段(线性dp)

题目链接&#xff1a;[TJOI2007] 线段 - 洛谷 思路&#xff1a; f[i][0]表示走完第i行且停在第i行的左端点最少用的步数 f[i][1]同理&#xff0c;停在右端点的最少步数。 那么转移就很简单了&#xff0c;走完当前行且停到左端点&#xff0c;那么一定是从右端点过来的&#x…

torch配置时出现问题

torch配置时出现如下问题&#xff1a; 可能原因&#xff1a; 1、下载的whl文件中python版本与本机上的python版本不匹配&#xff1b; 2、上图中的文件是64位的&#xff0c;而本机python是32位的&#xff0c;也无法匹配&#xff1b; 3、cuda的版本不匹配。

基于springboot实现的校园博客系统

开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven…

Word怎么画图?这5个方法收藏好!

“我需要在Word文档中画一些图&#xff0c;想问下Word应该怎么画图呢&#xff1f;有没有朋友可以帮我看看怎么操作呢&#xff1f;” 在今天的数字化时代&#xff0c;信息爆炸式增长&#xff0c;人们越来越需要高效、直观地传递和接收信息。而Word画图功能正是这一需求的完美体现…

黑马点评0——总览篇

&#x1f308;hello&#xff0c;你好鸭&#xff0c;我是Ethan&#xff0c;一名不断学习的码农&#xff0c;很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 &#x1f3c3;人生之义&#xff0c;在于追求&#xff0c;不在成败&#xff0c;勤通…

自己手写一个线性表List【C风格】

#include <iostream>//线性表、顺序表List#define MAX_SIZE 20 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0typedef int Status;//返回状态类型 typedef int ElemType;//元素类型//结构体 typedef struct {ElemType data[MAX_SIZE];//数据类型&#x…

泰坦尼克生还预测

文章目录 第1关&#xff1a;存活率与性别和船舱等级之间的关系第2关&#xff1a;各个口岸的生还率第3关&#xff1a;统计各登船口岸的登船人数以及生还率第4关&#xff1a;船客兄弟姐妹妻子丈夫的数量与生存率之间的关 第1关&#xff1a;存活率与性别和船舱等级之间的关系 编程…

04-Json/Ajax/Vue的知识

1. Json结构 1.1 Json概述 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式&#xff0c;实现数据前后端交互。 它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。 JSON采用完全独立于程序语言的文本格式。这些特性使JSON成为理想的数据交换…

Django性能优化:提升加载速度

title: Django性能优化&#xff1a;提升加载速度 date: 2024/5/20 20:16:28 updated: 2024/5/20 20:16:28 categories: 后端开发 tags: 缓存策略HTTP请求DNS查询CDN分发前端优化服务器响应浏览器缓存 第一章&#xff1a;Django性能优化概述 1.1 性能优化的意义 性能优化是…

探索移动云:我的ES与Kibana之旅

目录 引言&#xff1a; 如何免费体验移动云产品 登录并完成实名认证 选择试用ECS云主机 安全组配置 安装Elasticsearch和Kibana 安装Elasticsearch ​编辑安装kibana 测试结果 使用感觉 引言&#xff1a; 移动云技术产品的发展已经取得了巨大的进步。云数融合、A1、大…

【区域脑图论文笔记】BrainNetCNN:第一个专门为脑网络连接体数据设计的深度学习框架

【区域脑图论文笔记】BrainNetCNN&#xff1a;第一个专门为脑网络连接体数据设计的深度学习框架 信息概览与提炼采用的数据与结果数据集结果概览一眼 重点图与方法概览核心与优劣总结模型与实验论文方法E2E的理解E2N的理解N2G的理解三个卷积层设计的理解 论文实验与讨论 总结与…

必应搜索打开后出现Ref A,Ref B,Ref C是怎么回事

微软的垃圾产品&#xff0c;服务器还宕机了&#xff0c;当然访问不了

Apache Flink CDC 3.1.0版本知识学习

Apache Flink CDC 3.1.0版本知识学习 一、Flink CDC 3.1 快速预览二、Transformation 支持三、分库分表合并支持四、使用 Kafka Pipeline Sink 高效写入 Canal/Debezium 格式数据五、更高效地实时入湖 Paimon六、其他改进七、Flink CDC 3.1 版本兼容性 一、Flink CDC 3.1 快速预…

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

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

2024年电工杯数学建模A题思路分享 - 园区微电网风光储协调优化配置

# 1 赛题 A 题&#xff1a; 园区微电网风光储协调优化配置 园区微电网由风光发电和主电网联合为负荷供电&#xff0c;为了尽量提高风光电量的 负荷占比&#xff0c;需配置较高比例的风光发电装机容量&#xff0c;但由于园区负荷与风光发电功 率时序不匹配&#xff0c; 可能导致…

C语言-牛客-实现四舍五入

欢迎来到Harper.Lee的学习小世界&#xff01; 博主主页传送门&#xff1a;Harper.Lee的博客主页 想要一起进步的uu欢迎来后台找我哦&#xff01; 本篇博客总结C语言刷题的相关笔记~~~~ #牛客–实现四舍五入 题目描述&#xff1a;随机输入浮点数&#xff0c;输出四舍五入后的整数…