Qt布局管理详解(5种布局控件)(qt 布局)
ccwgpt 2024-09-21 13:53 43 浏览 0 评论
实际开发中,一个界面上可能包含十几个控件,手动调整它们的位置既费时又费力。作为一款成熟的 GUI 框架,Qt 提供了很多摆放控件的辅助工具(又称布局管理器或者布局控件),它们可以完成两件事:
- 自动调整控件的位置,包括控件之间的间距、对齐等;
- 当用户调整窗口大小时,位于布局管理器内的控件也会随之调整大小,从而保持整个界面的美观。
总之借助布局管理器,我们无需再逐个调整控件的位置和大小,可以将更多的精力放在软件功能的实现上。
Qt 共提供了 5 种布局管理器,每种布局管理器对应一个类,分别是 QVBoxLayout(垂直布局)、QHBoxLayout(水平布局)、QGridLayout(网格布局)、QFormLayout(表单布局)和 QStackedLayout(分组布局),它们的继承关系如下图所示:
QVBoxLayout垂直布局
垂直布局指的是将所有控件从上到下(或者从下到上)依次摆放,例如:
图 2 展示了 4 个 QPushButton 按钮利用 QVBoxLayout 垂直布局的效果。实际场景中,QVBoxLayout 中还可以放置其它控件,比如 QLabel 文本框、QLineEdit 单行输入框等。
程序中使用 QVBoxLayout 布局控件,需提前引入<QVBoxLayout>头文件。每个 QVBoxLayout 控件本质都是 QVBoxLayout 类的实例对象,该类提供了两个构造函数,分别是:
QVBoxLayout()
QVBoxLayout(QWidget *parent)
创建 QVBoxLayout 控件的同时可以指定父窗口,那么它将作为父窗口中管理其它控件的工具;也可以暂时不指定父窗口,待全部设置完毕后再将其添加到某个窗口中。
QVBoxLayout 类没有新增任何成员方法,它只能使用从父类继承的成员方法,下表给大家罗列了常用的一些:
表 1 QVBoxLayout常用方法
举个简单的例子:
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//创建主窗口
QWidget widget;
widget.setWindowTitle("QVBoxLayout垂直布局");
//创建垂直布局管理器
QVBoxLayout *layout=new QVBoxLayout;
//设置布局管理器中所有控件从下往上依次排列
layout->setDirection(QBoxLayout::BottomToTop);
//连续创建 3 个文本框,并设置它们的背景和字体大小
QLabel lab1("Label1");
lab1.setStyleSheet("QLabel{background:#dddddd;font:20px;}");
lab1.setAlignment(Qt::AlignCenter);
QLabel lab2("Label2");
lab2.setStyleSheet("QLabel{background:#cccccc;font:20px;}");
lab2.setAlignment(Qt::AlignCenter);
QLabel lab3("Label3");
lab3.setStyleSheet("QLabel{background:#ffffff;font:20px;}");
lab3.setAlignment(Qt::AlignCenter);
//将 3 个文本框和 2 个空白行添加到管理器中,它们的伸缩系数比是 2:1:2:3:3
layout->addStretch(2);
layout->addWidget(&lab1,1);
layout->addWidget(&lab2,2);
layout->addWidget(&lab3,3);
layout->addStretch(3);
//将布局管理器添加到 widget 窗口中
widget.setLayout(layout);
widget.show();
return a.exec();
}
程序中做了以下几个操作:
- 通过调用 setDirection() 方法,将添加到 QVBoxLayout 管理器中的所有控件(包括空白行)按照从下到上的顺序依次摆放。举个例子,由于 lab1 文本框是第二个添加到管理器中的,因此在最终显示的界面中,lab1 位于倒数第二的位置。
- 通过调用 addStrech() 方法,向管理器中先后添加了两个空白行,它们的伸缩系数分别为 2 和 3,因此 widget 窗口中的空白区域会平均分为 5 份,一个空白行占 3 份,另一个占 2 份。
- 通过调用 addWidget() 方法,向管理器中先后添加了 3 个文本框,它们的拉伸系数比为 1:2:3,所以当我们拉伸 widget 窗口时,三个文本框的大小(宽度)呈现 1:2:3 的关系。
- 通过调用 setLayout() 方法,成功地将 layout 布局管理器添加到了 widget 窗口中。当然,也可以在创建 layout 对象时指定 widget 作为它的父窗口,两种方式是完全等价的。
执行结果为:
图 3 QVBoxLayout 实例演示
QHBoxLayout水平布局
水平布局指的是将所有控件从左到右(或者从右到左)依次摆放,例如:
图 4 QHBoxLayout水平布局
【粉丝福利】Qt开发学习资料包、大厂面试题、项目视频、学习路线,包括(Qt C++基础,数据库编程,Qt项目实战、Qt框架、QML、Opencv、qt线程等等)有需要的可以进企鹅裙937552610领取哦~
使用 QHBoxLayout 水平布局控件,程序中要提前引入<QHBoxLayout>头文件。QHBoxLayout 和 QVBoxLayout 继承自同一个类,它们的用法非常相似,比如 QHBoxLayout 类也提供了两个构造函数:
QHBoxLayout()
QHBoxLayout(QWidget *parent)
QHBoxLayout 类也没有新添任何成员方法,它只能使用从父类继承的成员方法。因此,表 1 中罗列的所有成员方法也同样适用于 QHBoxLayout 对象。
注意,当 QHBoxLayout 对象调用表 1 中的 addStretch() 方法时,表示添加一个空白列。
举个简单的例子:
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QHBoxLayout>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//创建主窗口
QWidget widget;
widget.setWindowTitle("QHBoxLayout水平布局");
//创建水平布局管理器
QHBoxLayout *layout=new QHBoxLayout;
//设置布局管理器中所有控件的布局方向为从右往左依次排列
layout->setDirection(QBoxLayout::RightToLeft);
//连续创建 3 个文本框,并设置它们的背景和字体大小
QLabel lab1("Label1");
lab1.setStyleSheet("QLabel{background:#dddddd;font:20px;}");
lab1.setAlignment(Qt::AlignCenter);
QLabel lab2("Label2");
lab2.setStyleSheet("QLabel{background:#cccccc;font:20px;}");
lab2.setAlignment(Qt::AlignCenter);
QLabel lab3("Label3");
lab3.setStyleSheet("QLabel{background:#ffffff;font:20px;}");
lab3.setAlignment(Qt::AlignCenter);
//将 3 个文本框和 2 个空白列添加到管理器中,它们的拉伸系数比是 2:1:2:3:3
layout->addStretch(2);
layout->addWidget(&lab1,1);
layout->addWidget(&lab2,2);
layout->addWidget(&lab3,3);
layout->addStretch(3);
//将布局管理器添加到 widget 窗口中
widget.setLayout(layout);
widget.show();
return a.exec();
}
程序执行结果为:
图 5 QHBoxLayout水平布局实例
图 5 中,最左侧和最右侧各添加了一个空白列,它们的伸缩比例为 3:2,即它们的宽度比为 3:2。
QGridLayout网格布局
网格布局又称格栅布局或者表格布局,指的是将一些控件按照行和列排列在窗口上,例如:
图 6 QGridLayout网格布局
QGridLayout 的行标和列标都从 0 开始,例如图 6 中 one 按钮的位置为 (0, 0),Four 按钮的位置为 (2, 0)。我们可以随意指定 QGridLayout 的行数和列数,各个控件可以随意摆放,必要时某些位置可以空着不用。
使用 QGridLayout 网格控件,程序中需引入<QGridLayout>头文件。每个 QGridLayout 控件都是 QGridLayout 类的一个实例对象,该类提供了两个构造函数,分别是:
QGridLayout(QWidget *parent)
QGridLayout()
QGridLayout 类提供了很多实用的成员方法,常用的如下表所示:
表 2 QGridLayout常用方法
举个简单的例子:
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QGridLayout>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//创建主窗口
QWidget widget;
widget.setWindowTitle("QGridLayout网格布局");
//创建 4 个按钮和 1 个文本框
QPushButton *but1 = new QPushButton("but1");
QPushButton *but2 = new QPushButton("but2");
QLabel *lab3 = new QLabel("lab");
lab3->setStyleSheet("QLabel{background:#dddddd;font:20px;}");
lab3->setAlignment(Qt::AlignCenter);
QPushButton *but3 = new QPushButton("but3");
QPushButton *but4 = new QPushButton("but4");
//创建网格布局控件
QGridLayout *layout = new QGridLayout;
//向 layout 中添加控件,并指定各个控件的位置
layout->addWidget(but1, 0, 0);
layout->addWidget(but2, 0, 2);
layout->addWidget(lab3, 1, 0, 3, 3);
layout->addWidget(but3, 4, 0);
layout->addWidget(but4, 4, 2);
//将 layout 添加到 widget 窗口中
widget.setLayout(layout);
widget.show();
return a.exec();
}
程序运行结果为:
图 7 QGridLayout网格布局实例
图 7 中,文本框控件从 (1,0) 位置开始,占据了 3 行 3 列的表格空间。
QFormLayout表单布局
Qt 提供了很多种输入框控件,包括 QLineEdit 单行输入框、QTextEdit 多行输入框等。通常情况下,每个输入框的旁边都会附带一些文字(又称标签),用来提示用户需要输入的信息。例如,图 8 中第一个输入框的标签为 "Name",提示用户填写自己的姓名。
图 8 QFromLayout表单布局
生成图 8 这样的界面,实现的方法有很多,例如:
- 分别创建 3 个 QLabel 控件和 3 个 QLineEdit 控件,手动指定它们的位置;
- 在 QHBoxLayout 中嵌套 3 个 QVBoxLayout,又或者在 QVBoxLayout 中嵌套 3 个 QHBoxLayout,然后再添加 3 个 QLabel 控件和 3 个 QLineEdit 控件;
- 使用 QGridLayout 创建一个 3 行 2 列的表格,向表格中添加 3 个 QLabel 控件和 3 个 QLineEdit 控件。
- 使用 QFormLayout 表单布局控件实现。
【粉丝福利】Qt开发学习资料包、大厂面试题、项目视频、学习路线,包括(Qt C++基础,数据库编程,Qt项目实战、Qt框架、QML、Opencv、qt线程等等)有需要的可以进企鹅裙937552610领取哦~
第 1 种方法最大的弊端在于,各个控件的尺寸都是固定的,不会随着父窗口尺寸的改变而改变。第 2、3、4 种方法都是借助布局控件实现的,各个控件的尺寸可以自动调整,但前两种方法需要手动设置每一列的 strech 拉伸系数,而第 4 种方式不需要。总之对于生成类似图 8 这样的表单窗口,建议大家使用 QFormLayout 控件,因为使用 QFormLayout 编写的代码量最少,开发效率最高。
QFormLayout 可以容纳很多个输入框以及对应的标签,并将它们从上到下依次排列在界面上(如图 8 所示)。大多数情况下,QFormLayout 底层是用 QGridLayout 网格布局管理器实现的,和后者不同的是,QFormLayout 只包含 2 列(不限制行数),且第一列放置标签,第二列放置输入框。
使用 QFormLayout 布局控件之前,程序中应引入<QFormLayout>头文件。每一个表单布局控件都是 QFormLayout 类的一个实例对象,该类仅提供了一个构造函数:
QFormLayout(QWidget *parent = Q_NULLPTR)
下表给大家罗列了操作 QFormLayout 对象常用的一些成员方法:
表 3 QFormLayout常用方法
举个简单的例子:
#include <QApplication>
#include <QWidget>
#include <QLineEdit>
#include <QFormLayout>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//创建主窗口
QWidget widget;
widget.setWindowTitle("QFormLayout表单布局");
//创建 4 个按钮和 1 个文本框
QFormLayout* layout = new QFormLayout();
//设置表单中的标签都位于控件的上方
layout->setRowWrapPolicy(QFormLayout::WrapAllRows);
//添加 3 行输入框和标签
layout->addRow("Name:",new QLineEdit());
layout->addRow("Email:",new QLineEdit());
layout->addRow("Adress:",new QLineEdit());
//设置行间距和列间距为 10
layout->setSpacing(10);
//将 layout 表单添加到 widget 窗口中
widget.setLayout(layout);
widget.show();
return a.exec();
}
程序运行结果为:
图 9 QFormLayout表单布局实例
QStackedLayout分组布局
QStackedLayout 布局管理器可以容纳多个控件或者窗口,但每次只显示其中的一个。
举个简单的例子,下图中的界面就使用了 QStackedLayout 布局管理器:
图 10 QStackedLayout布局管理器
整个窗口被一分为二,左侧是 QListWidget 列表控件,右侧是 QStackedLayout 布局管理器。QStackedLayout 中包含 QPushButonn、QLabel 和 QLineEdit 这 3 个控件,但每次只能 3 个控件中的一个。
QStackedLayout 自身无法切换当前显示的控件或窗口,实际应用时通常和 QListWidget 或者 QComboBox 搭配使用。
使用 QStackedLayout 布局控件,程序中必须先引入<QStackedLayout>头文件。 每个 QStackedLayout 控件都是 QStackedLayout 类的一个实例对象,该类提供有 3 个构造函数,分别是:
QStackedLayout()
QStackedLayout(QWidget *parent)
QStackedLayout(QLayout *parentLayout)
借助第二个构造函数,我们可以将 QStackedLayout 添加到指定的 parent 窗口中;借助第三个构造函数,我们可以将 QStackedLayout 嵌入到指定的 parentLayout 布局控件中
本节学习的 5 种布局控件都可以嵌套使用,例如将 QVBoxLayout 放到 QHBoxLayout 内部、将 QGridLayout 放到 QStackedLayout 内部等。
下表罗列了操作 QStackedLayout 对象常用的一些成员方法:
表 4 QStackedLayout常用方法
这里我们以图 10 所示的窗口为例,实现代码如下:
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QStackedLayout>
#include <QListWidget>
#include <QHBoxLayout>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//创建主窗口
QWidget widget;
widget.setWindowTitle("QStackedLayout分组布局");
widget.resize(600,400);
//向主窗口中添加一个水平布局控件
QHBoxLayout *layout=new QHBoxLayout;
//创建一个列表
QListWidget listWidget(&widget);
listWidget.setMinimumWidth(150);
listWidget.setFont(QFont("宋体",14));
listWidget.addItem("QPushButton");
listWidget.addItem("QLabel");
listWidget.addItem("QLineEdit");
//新建 3 个窗口,分别放置文本框、按钮和单行输入框
QWidget widget1;
widget1.setMinimumSize(400,400);
QPushButton but1("这是一个按钮",&widget1);
QWidget widget2;
widget2.setMinimumSize(400,400);
QLabel lab1("这是一个文本框",&widget2);
QWidget widget3;
widget3.setMinimumSize(400,400);
QLineEdit edit("这是一个单行输入框",&widget3);
//创建一个分组布局,将 3 个窗口添加到分组控件中
QStackedLayout *stackedLayout = new QStackedLayout;
stackedLayout->addWidget(&widget1);
stackedLayout->addWidget(&widget2);
stackedLayout->addWidget(&widget3);
//layout 第一列添加 QListWidget 控件,第二列添加分组布局控件,设置它们的伸缩系数比为 1:4
layout->addWidget(&listWidget,1);
layout->addLayout(stackedLayout,4);
//将 layout 水平布局控件添加到 widget 窗口中
widget.setLayout(layout);
widget.show();
//连接信号和槽,实现当点击列表中的某一项,切换分组布局管理器显示的控件
QObject::connect(&listWidget,&QListWidget::currentRowChanged,stackedLayout,&QStackedLayout::setCurrentIndex);
return a.exec();
}
此程序中,我们在 QHBoxLayout 水平布局控件内又放置了一个 QStackedLayout 分组布局控件。感兴趣的读者可以编写程序,测试其它布局控件之间嵌套的效果。
相关推荐
- 十分钟让你学会LNMP架构负载均衡(impala负载均衡)
-
业务架构、应用架构、数据架构和技术架构一、几个基本概念1、pv值pv值(pageviews):页面的浏览量概念:一个网站的所有页面,在一天内,被浏览的总次数。(大型网站通常是上千万的级别)2、u...
- AGV仓储机器人调度系统架构(agv物流机器人)
-
系统架构层次划分采用分层模块化设计,分为以下五层:1.1用户接口层功能:提供人机交互界面(Web/桌面端),支持任务下发、实时监控、数据可视化和报警管理。模块:任务管理面板:接收订单(如拣货、...
- 远程热部署在美团的落地实践(远程热点是什么意思)
-
Sonic是美团内部研发设计的一款用于热部署的IDEA插件,本文其实现原理及落地的一些技术细节。在阅读本文之前,建议大家先熟悉一下Spring源码、SpringMVC源码、SpringBoot...
- springboot搭建xxl-job(分布式任务调度系统)
-
一、部署xxl-job服务端下载xxl-job源码:https://gitee.com/xuxueli0323/xxl-job二、导入项目、创建xxl_job数据库、修改配置文件为自己的数据库三、启动...
- 大模型:使用vLLM和Ray分布式部署推理应用
-
一、vLLM:面向大模型的高效推理框架1.核心特点专为推理优化:专注于大模型(如GPT-3、LLaMA)的高吞吐量、低延迟推理。关键技术:PagedAttention:类似操作系统内存分页管理,将K...
- 国产开源之光【分布式工作流调度系统】:DolphinScheduler
-
DolphinScheduler是一个开源的分布式工作流调度系统,旨在帮助用户以可靠、高效和可扩展的方式管理和调度大规模的数据处理工作流。它支持以图形化方式定义和管理工作流,提供了丰富的调度功能和监控...
- 简单可靠高效的分布式任务队列系统
-
#记录我的2024#大家好,又见面了,我是GitHub精选君!背景介绍在系统访问量逐渐增大,高并发、分布式系统成为了企业技术架构升级的必由之路。在这样的背景下,异步任务队列扮演着至关重要的角色,...
- 虚拟服务器之间如何分布式运行?(虚拟服务器部署)
-
在云计算和虚拟化技术快速发展的今天,传统“单机单任务”的服务器架构早已难以满足现代业务对高并发、高可用、弹性伸缩和容错容灾的严苛要求。分布式系统应运而生,并成为支撑各类互联网平台、企业信息系统和A...
- 一文掌握 XXL-Job 的 6 大核心组件
-
XXL-Job是一个分布式任务调度平台,其核心组件主要包括以下部分,各组件相互协作实现高效的任务调度与管理:1.调度注册中心(RegistryCenter)作用:负责管理调度器(Schedule...
- 京东大佬问我,SpringBoot中如何做延迟队列?单机与分布式如何做?
-
京东大佬问我,SpringBoot中如何做延迟队列?单机如何做?分布式如何做呢?并给出案例与代码分析。嗯,用户问的是在SpringBoot中如何实现延迟队列,单机和分布式环境下分别怎么做。这个问题其实...
- 企业级项目组件选型(一)分布式任务调度平台
-
官网地址:https://www.xuxueli.com/xxl-job/能力介绍架构图安全性为提升系统安全性,调度中心和执行器进行安全性校验,双方AccessToken匹配才允许通讯;调度中心和执...
- python多进程的分布式任务调度应用场景及示例
-
多进程的分布式任务调度可以应用于以下场景:分布式爬虫:importmultiprocessingimportrequestsdefcrawl(url):response=re...
- SpringBoot整合ElasticJob实现分布式任务调度
-
介绍ElasticJob是面向互联网生态和海量任务的分布式调度解决方案,由两个相互独立的子项目ElasticJob-Lite和ElasticJob-Cloud组成。它通过弹性调度、资源管控、...
- 分布式可视化 DAG 任务调度系统 Taier 的整体流程分析
-
Taier作为袋鼠云的开源项目之一,是一个分布式可视化的DAG任务调度系统。旨在降低ETL开发成本,提高大数据平台稳定性,让大数据开发人员可以在Taier直接进行业务逻辑的开发,而不用关...
- SpringBoot任务调度:@Scheduled与TaskExecutor全面解析
-
一、任务调度基础概念1.1什么是任务调度任务调度是指按照预定的时间计划或特定条件自动执行任务的过程。在现代应用开发中,任务调度扮演着至关重要的角色,它使得开发者能够自动化处理周期性任务、定时任务和异...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- MVC框架 (46)
- spring框架 (46)
- 框架图 (58)
- flask框架 (53)
- quartz框架 (51)
- abp框架 (47)
- jpa框架 (47)
- laravel框架 (46)
- springmvc框架 (49)
- 分布式事务框架 (65)
- scrapy框架 (56)
- shiro框架 (61)
- 定时任务框架 (56)
- java日志框架 (61)
- JAVA集合框架 (47)
- grpc框架 (55)
- ppt框架 (48)
- 内联框架 (52)
- winform框架 (46)
- gui框架 (44)
- cad怎么画框架 (58)
- ps怎么画框架 (47)
- ssm框架实现登录注册 (49)
- oracle字符串长度 (48)
- oracle提交事务 (47)