Qt_布局管理器

server/2024/9/20 10:46:43/

目录

1、QVBoxLayout垂直布局

1.1 QVBoxLayout的使用

1.2 多个布局管理器 

2、QHBoxLayout水平布局 

2.1 QHBoxLayout的使用

2.2 嵌套的Layout 

3、QGridLayout网格布局 

3.1  QGridLayout的使用

3.2 设置控件大小比例 

4、QFormLayout 

4.1  QFormLayout的使用

5、QSpacerItem 

5.1 QSpacerItem的使用

结语 


前言:

        使用Qt时,在没有布局管理器(Layout)概念之前,在界面上创建控件都是用“绝对定位”来设置的,即调用setGeometry或move函数摆放,或者直接在ui文件中对控件进行手动的摆放,这些方式都会导致界面上的控件摆放存在偏差,影响整体美观。因此引入布局管理器机制,将界面上的控件都直接放到布局管理器下,布局管理器会自动对这些控件进行位置大小的调整,让整个界面看起来更加规整。

1、QVBoxLayout垂直布局

         QVBoxLayout表示垂直布局管理器,他也是一个控件,只不过该控件的作用是对内部的其他控件进行规整摆放。QVBoxLayout属性介绍如下:

layoutLeftMargin
左侧边距
layoutRightMargin
右侧边距
layoutTopMargin
上方边距
layoutBottomMargin
下方边距
layoutSpacing
相邻元素之间的间距

        与QVBoxLayout相关的常用接口:

addWidget(QWidget*)
把控件添加到布局管理器中
setLayout(QLayout*)是QWidget的接口,用于将布局管理器设置到widget下

1.1 QVBoxLayout的使用

        创建一个QVBoxLayout和三个按钮控件,将三个按钮控件放到该QVBoxLayout下,观察生成后的界面,代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QVBoxLayout>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QVBoxLayout* qv = new QVBoxLayout();//创建垂直布局管理器//创建三个按钮QPushButton* qp1 = new QPushButton("按钮1");QPushButton* qp2 = new QPushButton("按钮2");QPushButton* qp3 = new QPushButton("按钮3");//将三个按钮放到管理器下qv->addWidget(qp1);qv->addWidget(qp2);qv->addWidget(qp3);//将管理器设置到当前widge下this->setLayout(qv);}Widget::~Widget()
{delete ui;
}

        运行结果:

        从结果可以发现三个按钮规章有序的显示在界面上,并且对widget界面进行拉伸时,这三个按钮也会跟着拉伸的比例变化,如果这三个按钮直接放到widget界面上,则按钮尺寸不会随着widget界面的尺寸变化而变化。能够实现这个效果的原因是布局管理器作用在widget上,换句话说,一个widget只能有一个布局管理器并且布局管理器就是widget本身,所以对widget界面进行尺寸拉伸时,实际上就是对布局管理器做拉伸,进而导致布局管理器里的控件也跟着拉伸了

1.2 多个布局管理器 

        虽然一个widget下只能有一个布局管理器,但是可以通过ui文件中界面创建的方式在一个widget下生成多个布局管理器,操作如下:

        但是在运行程序后,发现对最终的界面进行拖拽则无法影响界面上的按钮,如下图:

        原因是通过ui文件手动式创建的Layout,实际上是先创建了一个widget,然后再将创建的Layout放到该widget下,所以上述界面中有3个widget,而我们拖拽的是最外层的widget尺寸,不会影响里面两个widget的尺寸,也就不会影响Layout里的按钮的尺寸了。

2、QHBoxLayout水平布局 

         QHBoxLayout表示水平布局管理器,他的作用和QVBoxLayout是一样的,不过他是在水平方向摆放控件的,QHBoxLayout效果图如下:

        QHBoxLayout属性以及常用接口都和QVBoxLayout一样,因此这里就不再介绍了。

2.1 QHBoxLayout的使用

        创建一个QHBoxLayout和三个按钮控件,将三个按钮控件放到该QHBoxLayout下,观察生成后的界面,代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QHBoxLayout>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建水平布局管理器QHBoxLayout* qh = new QHBoxLayout();//创建三个按钮QPushButton* q1 = new QPushButton("按钮1");QPushButton* q2 = new QPushButton("按钮2");QPushButton* q3 = new QPushButton("按钮3");//将按钮添加到管理器中qh->addWidget(q1);qh->addWidget(q2);qh->addWidget(q3);//将管理器设置进当前widget中this->setLayout(qh);
}Widget::~Widget()
{delete ui;
}

        运行结果:

2.2 嵌套的Layout 

        在上述水平布局管理中添加一个垂直布局管理器,观察最终的现象,代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QHBoxLayout>
#include <QPushButton>
#include <QVBoxLayout>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建水平布局管理器QHBoxLayout* qh = new QHBoxLayout();//创建三个按钮QPushButton* q1 = new QPushButton("按钮1");QPushButton* q2 = new QPushButton("按钮2");QPushButton* q3 = new QPushButton("按钮3");//将按钮添加到管理器中qh->addWidget(q1);qh->addWidget(q2);qh->addWidget(q3);//将管理器设置进当前widget中this->setLayout(qh);//创建小Layout-垂直管理器QVBoxLayout* qh1 = new QVBoxLayout();//创建三个按钮QPushButton* q4 = new QPushButton("按钮4");QPushButton* q5 = new QPushButton("按钮5");QPushButton* q6 = new QPushButton("按钮6");//将按钮添加到小的垂直管理器中qh1->addWidget(q4);qh1->addWidget(q5);qh1->addWidget(q6);//将小垂直管理器添加到水平管理器中qh->addLayout(qh1);}Widget::~Widget()
{delete ui;
}

         运行结果:

        从上述的例子中可以总结一点:垂直布局管理器的控件添加方式是从下往上式的添加,而水平布局管理器是从右往左式的添加控件。 

3、QGridLayout网格布局 

         QGridLayout表示网格布局,通俗来说就是水平和垂直布局的结合版,就如同一个二维数组,内部的控件就是数值上的元素。QGridLayout属性相比于上述两个控件的区别是:

layoutHorizontalSpacing
相邻元素之间⽔平⽅向的间距
layoutVerticalSpacing
相邻元素之间垂直⽅向的间距
layoutRowStretch
⾏⽅向的拉伸系数
layoutColumnStretch
列⽅向的拉伸系数

        QGridLayout的常用接口和上述两个控件也几乎相同。

3.1  QGridLayout的使用

        创建一个QGridLayout和四个按钮控件,将这四个按钮控件放到QGridLayout下,观察生成的界面,代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QGridLayout>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建QGridLayoutQGridLayout* qg = new QGridLayout();//创建四个按钮QPushButton* p1 = new QPushButton("按钮1");QPushButton* p2 = new QPushButton("按钮2");QPushButton* p3 = new QPushButton("按钮3");QPushButton* p4 = new QPushButton("按钮4");//将按钮添加到QGridLayout中,注意表明出坐标qg->addWidget(p1,0,0);qg->addWidget(p2,0,1);qg->addWidget(p3,1,0);qg->addWidget(p4,1,1);this->setLayout(qg);}Widget::~Widget()
{delete ui;
}

        运行结果:

        可以从结果看到,界面上既能完成垂直布局,又能完成水平布局。

3.2 设置控件大小比例 

        在QGridLayout中,可以设置以行、列为单位设置控件的拉伸系数,比如调用函数setColumnStretch就是设置列上所有控件的拉伸系数,调用函数setRowStretch就是设置行上所有控件的拉伸系数。注意设置拉伸系数不等于直接设置尺寸,拉伸系数表示与当前单位与其他单位的长度比例。例子如下:

        ①设置列拉伸(水平方向拉伸控件):

#include "widget.h"
#include "ui_widget.h"
#include <QGridLayout>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建QGridLayoutQGridLayout* qg = new QGridLayout();//创建四个按钮QPushButton* p1 = new QPushButton("按钮1");QPushButton* p2 = new QPushButton("按钮2");QPushButton* p3 = new QPushButton("按钮3");QPushButton* p4 = new QPushButton("按钮4");//将按钮添加到QGridLayout中,注意表明出坐标qg->addWidget(p1,0,0);qg->addWidget(p2,0,1);qg->addWidget(p3,1,0);qg->addWidget(p4,1,1);this->setLayout(qg);qg->setColumnStretch(0,1);//设置该列的拉伸系数是1qg->setColumnStretch(1,3);//设置该列的拉伸系数是3//则该第1列的长度是第0列的三倍
}Widget::~Widget()
{delete ui;
}

        运行结果:

        结果是第1列的长度是第0列的三倍。


        ②设置列拉伸(垂直方向拉伸控件):

#include "widget.h"
#include "ui_widget.h"
#include <QGridLayout>
#include <QPushButton>
#include <QSizePolicy>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建QGridLayoutQGridLayout* qg = new QGridLayout();//创建四个按钮QPushButton* p1 = new QPushButton("按钮1");QPushButton* p2 = new QPushButton("按钮2");QPushButton* p3 = new QPushButton("按钮3");QPushButton* p4 = new QPushButton("按钮4");//因为每个按钮的垂直尺寸是固定的,因此要手动将按钮的垂直属性设置为拓展,目的是方便观察p1->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Expanding);p2->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Expanding);p3->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Expanding);p4->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Expanding);//将按钮添加到QGridLayout中,注意表明出坐标qg->addWidget(p1,0,0);qg->addWidget(p2,0,1);qg->addWidget(p3,1,0);qg->addWidget(p4,1,1);this->setLayout(qg);qg->setRowStretch(0,1);//设置该行的拉伸系数是1qg->setRowStretch(1,3);//设置该行的拉伸系数是3//则该第1行的长度是第0行的三倍
}Widget::~Widget()
{delete ui;
}

        运行结果:

4、QFormLayout 

        QFormLayout表示表单布局,QFormLayout的功能就比较单一了,他是专门实现只有两列的表单,可以看成是QGridLayout的一个分支控件,因此QFormLayout的属性和QGridLayout几乎一样,只是QFormLayout的添加控件接口为addRow,该接口介绍如下:

void addRow(QWidget *label, QWidget *field);
// 第⼀个控件固定是QLabel, 第⼆个控件可以是任意控件
// 如果把第⼀个参数填写为NULL, 则第一列什么都不显⽰,但是第二个参数不能为空

4.1  QFormLayout的使用

        QFormLayout常用于填写信息的场景, 因此模拟一个信息表单,首先创建一个QFormLayout ,和三个QLabel以及三个QLineEdit,实现代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QFormLayout>
#include <QLineEdit>
#include <QLabel>
#include <QPushButton>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建QFormLayoutQFormLayout* qf = new QFormLayout;//创建三对QLabel和QLineEditQLabel* q1 = new QLabel("姓名");QLabel* q2 = new QLabel("电话");QLabel* q3 = new QLabel("地址");QLineEdit* ql1 = new QLineEdit;QLineEdit* ql2 = new QLineEdit;QLineEdit* ql3 = new QLineEdit;//创建提交按钮QPushButton* qp = new QPushButton("提交");//将上述控件添加到QFormLayout中qf->addRow(q1,ql1);qf->addRow(q2,ql2);qf->addRow(q3,ql3);qf->addRow(nullptr,qp);this->setLayout(qf);
}Widget::~Widget()
{delete ui;
}

        运行结果:

5、QSpacerItem 

        QSpacerItem表示一段空白,他的作用是在使⽤布局管理器的时候,可能需要在控件之间添加⼀段空⽩,这时候就可以用QSpacerItem了。QSpacerItem属性介绍如下:

width
QSpacerItem的 宽度
height
QSpacerItem的 ⾼度
hData
拉伸时,⽔平⽅向的 sizePolicy 的布局设置
vData
拉伸时, 垂直⽅向的 sizePolicy 的布局设置

5.1 QSpacerItem的使用

        创建一个布局管理器,和两个按钮控件以及一个QSpacerItem,观察没有QSpacerItem的界面和有QSpacerItem的界面的区别,代码如下:

#include "widget.h"
#include "ui_widget.h"
#include <QPushButton>
#include <QHBoxLayout>
#include <QSpacerItem>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//创建一个布局管理器(水平或垂直都行)QHBoxLayout* qh = new QHBoxLayout();//创建两个按钮QPushButton* qp1 = new QPushButton("按钮1");QPushButton* qp2 = new QPushButton("按钮2");//创建QSpacerItemQSpacerItem* qs = new QSpacerItem(100,1);//初始化长、宽//将按钮放入布局管理器中qh->addWidget(qp1);qh->addSpacerItem(qs);qh->addWidget(qp2);this->setLayout(qh);
}Widget::~Widget()
{delete ui;
}

         测试结果:

结语 

        以上就是关于布局管理器的讲解,布局管理器整体使用难度不高,但他却是Qt开发中较为重要的一个控件,因为他保证了界面的规整度,同时也方便了开发者对控件规划的位置计算。

        最后如果本文有遗漏或者有误的地方欢迎大家在评论区补充,谢谢大家!!     


http://www.ppmy.cn/server/119372.html

相关文章

Modbus_tcp

目录 一&#xff1a;modbus起源 1.起源 2. 分类&#xff1a; 3. 优势&#xff1a; 4. 应用场景&#xff1a; 5.ModbusTCP特点&#xff08;掌握&#xff09;&#xff1a; 二、 ModbusTCP的协议 1. 报文头 2. 寄存器 1. 线圈&#xff08;Coils&#xff09; 2. 离…

openmv与stm32通信

控制小车视觉循迹使用 OpenMV 往往是不够的。一般使用 OpenMV 对图像进行处理&#xff0c;将处理过后的数据使用串口发送给STM32&#xff0c;使用STM32控制小车行驶。本文主要讲解 OpenMV 模块与 STM32 间的串口通信以及两种循迹方案&#xff0c;分别是划分检测区域和线性回归。…

每日刷题(算法)

我们N个真是太厉害了 思路&#xff1a; 我们先给数组排序&#xff0c;如果最小的元素不为1&#xff0c;那么肯定是吹牛的&#xff0c;我们拿一个变量记录前缀和&#xff0c;如果当前元素大于它前面所有元素的和1&#xff0c;那么sum1是不能到达的值。 代码&#xff1a; #def…

第十一章 【后端】商品分类管理微服务(11.5)——增强响应

11.5 增强响应 在前后端分离的开发模式下,我们一般会统一后端的响应格式,比如自定义 Response 结构,但每个开发者可能会封装各自的 Response 结构,造成不一致,因此我们需要将响应格式统一起来,定义一个统一的标准响应格式。 11.5.1 创建响应模块 新建 yumi-etms-respon…

[PTA]7-1 藏头诗

[PTA]7-1 藏头诗 本题要求编写一个解密藏头诗的程序。 注&#xff1a;在 2022 年 7 月 14 日 16 点 50 分以后&#xff0c;该题数据修改为 UTF-8 编码。 输入格式&#xff1a; 输入为一首中文藏头诗&#xff0c;一共四句&#xff0c;每句一行。注意&#xff1a;一个汉字占三…

WPF经典面试题全集

以下是一些常见的WPF&#xff08;Windows Presentation Foundation&#xff09;经典面试题及其答案详解&#xff1a; 1. WPF 是什么&#xff1f;与 WinForms 有何区别&#xff1f; 答案&#xff1a; WPF 是 Windows Presentation Foundation&#xff0c;是微软开发的用于构建…

关系运算符

判断相等或者不等的运算符&#xff0c;一般被称为关系运算符。 相等和不相等 C/C/Java/C#使用””表示相等&#xff0c;””表示赋值&#xff0c;”!”代表不相等。C/C无法根据使用场景区分赋值和相等运算符&#xff0c;因为支持赋值运算符返回整数并作为判断条件。VB用””判…

C++编译环境(IDE)推荐及安装

IDE是什么 嗨嗨嗨&#xff0c;我又来水博文了 今天来给大家推荐几款好用的IDE IDE是集成开发环境&#xff08;Integrated Development Environment&#xff09;的缩写&#xff0c;是一种软件应用程序&#xff0c;提供了用于软件开发的各种工具和功能&#xff0c;包括代码编辑…

GPT-4论文阅读

GPT-4 Technical Report论文阅读 文章目录 GPT-4 Technical Report论文阅读 Abstract训练的稳定性Training processPredictable scaling训练的稳定性多么难能可贵 Capabilities考试成绩传统的benchmark语言方面的能力Visual inputsSteerability LimitationsRisks & mitigat…

油猴脚本抓取swagger参数,自动生成请求参数

前端开发 &#xff0c;从 swagger中获取api 以及 参数复制黏贴很麻烦 &#xff1b;写一个脚本直接生成复制需要的形式 脚本代码&#xff1a; // UserScript // name swagger.io // namespace http://tampermonkey.net/ // version 2024-09-18 // descriptio…

ATGM331C-5T杭州中科微BDS/GNSS全星座定位授时模块应用领域

ATGM331C-5T 系列模块全部支持辅助 GNSS &#xff08;AGNSS&#xff09;功能&#xff1b;支持精确秒脉冲输出&#xff0c;脉冲上升沿与 UTC 时间对齐。 产品选型&#xff1a; 性能指标&#xff1a; 出色的定位导航功能&#xff0c;支持 BDS/GPS 卫星导航系统的单系统授时&#…

vue3项目接入Web Office开放平台

官网地址&#xff1a; 快速开始-WebOffice 知识库 1、根据需要下载对应SDK包 JSSDK 更新日志-WebOffice 知识库 2、先引入下载的sdk包&#xff0c;我这里引入的es6的包 import WebOfficeSDK from ./web-office-sdk-v1.1.3.es;3、在Html中找一个容器给上ID&#xff0c;等会要…

Linux运维篇-服务器简介

目录 前言服务器分类&#xff08;按服务器的机箱结构来划分&#xff09;台式服务器机架式服务器刀片式服务器 外观部件内部结构前面板前面板组件前面板接口说明前面板指示灯和按钮前面板指示灯/按钮说明 后面板后面板组件后面板接口说明后面板指示灯后面板指示灯说明 主板和 iB…

使用Spring Boot开发自习室预定系统

开发一个自习室预定系统涉及到用户管理、自习室管理、预定管理等功能。以下是使用Spring Boot开发自习室预定系统的步骤和关键点&#xff1a; 1. 需求分析 确定系统的基本需求&#xff0c;例如&#xff1a; 用户注册和登录管理员管理自习室信息用户浏览可用自习室用户预定自…

外国药品位置检测系统源码分享

外国药品位置检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer…

etcd之etcd简介和安装(一)

1、etcd简介 1.1 etcd简介 etcd 是开源的、高可用的分布式key-value存储系统&#xff0c;可用于配置共享和服务的注册和发现&#xff0c;它专注于&#xff1a; 简单&#xff1a;定义清晰、面向用户的API&#xff08;gRPC&#xff09; 安全&#xff1a;可选的客户端TLS证书自…

java项目开发1

manven安装,解压 解压到文件夹 点击bin后复制地址 配置环境变量在path里面新建&#xff0c;复制地址后确定关闭 在命令行输入cmd 用记事本打开settings配置本地仓库 修改localRepository 在所用的盘里建文件夹MavenJar仓库 修改阿里云镜像 <mirror><id>nexus-aliyu…

Redis 主从复制配置教程

1. 什么是 Redis 主从复制 Redis 主从复制&#xff08;Master-Slave Replication&#xff09;允许一个 Redis 实例作为主节点&#xff08;Master&#xff09;&#xff0c;多个 Redis 实例作为从节点&#xff08;Slave&#xff09;&#xff0c;从节点会自动同步主节点的数据&am…

[数据集][目标检测]智慧交通铁路异物入侵检测数据集VOC+YOLO格式802张7类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;802 标注数量(xml文件个数)&#xff1a;802 标注数量(txt文件个数)&#xff1a;802 标注类别…

【前端】ES6:Set与Map

文章目录 1 Set结构1.1 初识Set1.2 实例的属性和方法1.3 遍历1.4 复杂数据结构去重 2 Map结构2.1 初识Map2.2 实例的属性和方法2.3 遍历 1 Set结构 它类似于数组&#xff0c;但成员的值都是唯一的&#xff0c;没有重复的值。 1.1 初识Set let s1 new Set([1, 2, 3, 2, 3]) …