QT-布局管理器

Qt布局管理器

一、布局管理器介绍

布局管理器(Layout Manager)是在图形用户界面(GUI)应用程序中用于自动管理和排列窗口部件(Widget)的工具。

Qt 共提供了 5 种布局管理器,来帮助开发者方便地组织和管理窗口部件。每种布局管理器对应一个类,分别是 QVBoxLayout(垂直布局)、QHBoxLayout(水平布局)、QGridLayout(网格布局)、QFormLayout(表单布局)和 QStackedLayout(分组布局),继承关系如下图:

在这里插入图片描述

1. 顶层基类
  • QObject:Qt 所有对象的基类,提供对象树、信号与槽、事件机制等核心功能,让布局类能融入 Qt 对象体系。
  • QLayoutItem:布局项的抽象基类,定义了布局元素(如控件、子布局)的通用接口(尺寸、位置计算等),让布局系统能统一处理不同 “布局单元”。
2. 核心抽象类:QLayout

继承自 QObject + QLayoutItem,是所有具体布局类的 “父模板”,定义了布局的核心逻辑(如添加子项、计算尺寸、设置父部件等),但本身不实现具体布局规则(需子类扩展)。

3. 具体布局子类(常用布局)

QLayout 的子类,实现了不同界面排列规则,是实际开发中直接用的布局:

  • QBoxLayout:“盒子布局” 抽象类,分水平 / 垂直两种具体布局:
    • QVBoxLayout:垂直排列(控件从上到下叠)。
    • QHBoxLayout:水平排列(控件从左到右排)。
  • QGridLayout:网格布局,控件按 行、列 表格化排列,支持跨行 / 跨列。
  • QFormLayout:表单布局,自动排列 “标签(Label)+ 控件(如输入框)” 的表单结构,适合做设置界面。
  • QStackedLayout:栈式布局,同一时间只显示 一个页面(像选项卡切换、向导页),需配合 QStackedWidget 用。
二、可视化布局设计
1、Qt布局组件

Qt Designer 支持多种布局管理器,如垂直布局 (QVBoxLayout)、水平布局 (QHBoxLayout) 和网格布局 (QGridLayout)。可以通过右键点击设计区域并选择Layouts来应用布局管理器。

在这里插入图片描述

将布局管理器从工具箱拖拽到设计区域,并把控件放入到布局对应的红色框内部,,控件将被自动排列。
在这里插入图片描述

布局属性:

在这里插入图片描述

  • layoutLeftMargin属性,用来设定布局内部所有子控件与布局左边界之间的固定间距。Margin:边际
  • layoutTopMarginlayoutRightMarginlayoutBottomMargin,分别对应于顶部、右侧和底部的边距控制。
  • layoutSpacing属性在QVBoxLayout中用于控制布局内相邻子控件之间的垂直间距。
  • layoutStretch属性在QVBoxLayout中用于控制布局内各个子控件在分配剩余空间时的拉伸比例。Stretch:拉伸
2、工具栏按钮

在Qt Designer设计区域的工具栏中,也提供有布局操作按钮,提供便捷操作,如图所示。

在这里插入图片描述

三、QVBoxLayout(垂直布局管理器)

垂直布局管理器将所有控件从上到下的顺序依次排列窗口部件。如图,将一组QLabel标签进行垂直方向布局。

在这里插入图片描述

实现案例代码如下:

Widget_02::Widget_02(QWidget *parent) :  // 构造函数,参数 parent 指定父窗口QWidget(parent),                       // 调用 QWidget 的构造函数ui(new Ui::Widget_02)                  // 创建 UI 对象
{ui->setupUi(this);                     // 初始化并加载 Qt Designer 生成的 UI 界面// 创建一个垂直布局管理器,父对象为当前窗口QVBoxLayout* vlayout = new QVBoxLayout(this);QLabel* b1 = new QLabel;               // 创建第一个标签QLabel* b2 = new QLabel;               // 创建第二个标签QLabel* b3 = new QLabel;               // 创建第三个标签b1->setStyleSheet("background-color:red");   // 设置 b1 背景色为红色b2->setStyleSheet("background-color:blue");  // 设置 b2 背景色为蓝色b3->setStyleSheet("background-color:green"); // 设置 b3 背景色为绿色vlayout->addWidget(b1);                // 将 b1 添加到垂直布局vlayout->addWidget(b2);                // 将 b2 添加到垂直布局vlayout->addWidget(b3);                // 将 b3 添加到垂直布局vlayout->setSpacing(0);                // 设置布局中控件间的间距为 0vlayout->setContentsMargins(0,0,0,0);  // 设置布局外边距为 0(左、上、右、下)vlayout->setStretch(0,1);              // 设置 b1 拉伸比例为 1vlayout->setStretch(1,2);              // 设置 b2 拉伸比例为 2vlayout->setStretch(2,3);              // 设置 b3 拉伸比例为 3
}

🔑 总结

  1. 垂直布局
    • 使用 QVBoxLayout 将多个控件垂直排列。
    • addWidget() 按顺序添加控件。
  2. 控件样式
    • 使用 setStyleSheet() 设置背景颜色。(StyleSheet层叠样式表)
  3. 布局间距
    • setSpacing(0) → 控件之间没有空隙
    • setContentsMargins(0,0,0,0) → 布局外边距为 0
  4. 拉伸比例
    • setStretch(index, ratio) 控制控件在布局中占据空间的比例:
      • b1:b2:b3 = 1:2:3 → 高度按比例分配
  • 参数说明

    • index

      • 表示布局中控件的下标(顺序索引),从 0 开始。
      • 例如:如果你用 vlayout->addWidget(b1) 添加控件,b1 的下标就是 0,b2 的下标是 1,b3 的下标是 2。
    • stretch(比例)

      • 表示该控件在布局中占用剩余空间的相对比例
      • 比例越大,控件分配到的空间就越多。
四、QHBoxLayout(水平布局)

水平布局指的是将所有控件从左到右(或者从右到左)依次摆放。如图,将一组QLabel标签进行水平方向布局。

在这里插入图片描述

五、QGridLayout(网格布局)

网格布局又称格栅布局或者表格布局,指的是将一些控件按照行和列排列在窗口上。例如:将5个QLabel标签按照行列的方式进行网格布局。

在这里插入图片描述

常用函数:

// 1、添加控件
void addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment = Qt::Alignment())
void addWidget(QWidget *widget, int fromRow, int fromColumn, int rowSpan, int columnSpan, Qt::Alignment alignment = Qt::Alignment())
// 2、设置拉伸系数
void setColumnStretch(int column, int stretch)    // 给指定列设置拉伸系数
void setRowStretch(int row, int stretch)    // 给指定行设置拉伸系数
函数作用参数说明
setColumnStretch()设置列的拉伸比例column:列索引,stretch:拉伸比例
setRowStretch()设置行的拉伸比例row:行索引,stretch:拉伸比例
  • 核心思想:按比例分配布局剩余空间,而不会改变控件的最小尺寸或固定尺寸。
  • 可以配合 网格布局中的 addWidget() 使用,实现灵活的行列伸缩。

案例:

Widget_03::Widget_03(QWidget *parent) :  // 构造函数,参数 parent 指定父窗口QWidget(parent),                        // 调用 QWidget 的构造函数ui(new Ui::Widget_03)                   // 创建 UI 对象
{ui->setupUi(this);                      // 初始化并加载 Qt Designer 生成的 UI 界面QGridLayout* glayout = new QGridLayout(this); // 创建一个网格布局,父对象为当前窗口QLabel* b1 = new QLabel;                // 创建标签 b1QLabel* b2 = new QLabel;                // 创建标签 b2QLabel* b3 = new QLabel;                // 创建标签 b3QLabel* b4 = new QLabel;                // 创建标签 b4QLabel* b5 = new QLabel;                // 创建标签 b5b1->setStyleSheet("background-color:red");    // 设置 b1 背景色为红色b2->setStyleSheet("background-color:blue");   // 设置 b2 背景色为蓝色b3->setStyleSheet("background-color:green");  // 设置 b3 背景色为绿色b4->setStyleSheet("background-color:yellow"); // 设置 b4 背景色为黄色b5->setStyleSheet("background-color:#abc");   // 设置 b5 背景色为 #abc(浅蓝色)glayout->addWidget(b1, 0, 0);           // b1 放在第 0 行,第 0 列glayout->addWidget(b2, 0, 1);           // b2 放在第 0 行,第 1 列glayout->addWidget(b3, 1, 0, 1, 2, Qt::AlignCenter); // b3 放在第 1 行,第 0 列,跨 1 行、2 列,并居中对齐glayout->addWidget(b4, 2, 0);           // b4 放在第 2 行,第 0 列glayout->addWidget(b5, 2, 1);           // b5 放在第 2 行,第 1 列glayout->setHorizontalSpacing(0);       // 设置水平间距为 0glayout->setVerticalSpacing(0);         // 设置垂直间距为 0
}

🔑 总结

  1. 网格布局(QGridLayout)
    • 控件按行列放置,类似表格。
    • addWidget(widget, row, column) → 放置控件到指定行列
    • 可选参数:rowSpancolumnSpan → 控件跨多少行多少列
    • 可选参数:alignment → 控件对齐方式(居中、左对齐等)
  2. 控件样式
    • 使用 setStyleSheet() 设置背景颜色
  3. 间距
    • setHorizontalSpacing() → 控件列间距
    • setVerticalSpacing() → 控件行间距
  4. 布局效果
    • 形成一个 3 行 2 列的网格,b3 跨整行并居中显示
    • 每个标签显示不同颜色
六、QFormLayout(表单布局)

一行一行成对的,类似键值对。

QFormLayout特别适用于将一系列标签和输入控件组织成成对格式的用户界面设计,比如注册页面,每一个输入控件都有一个与之关联的标签。

在这里插入图片描述

常用函数:

// 1、添加控件
// 将指定的 field 控件和存储标签的 label 控件添加到表单布局的末尾
void addRow(QWidget *label, QWidget *field)    
// label:标签控件(QLabel)
// field:实际控件(QLineEdit、QComboBox等)
// 功能:把标签和控件组合成一行,添加到表单布局末尾// 将指定的 field 控件和 labelText 标签添加到表单布局的末尾
void addRow(const QString &labelText, QWidget *field)   
// labelText:标签的文字内容(QString),内部会自动创建 QLabel
// field:实际控件
// 功能:更简单,直接用文字创建标签,不必手动创建 QLabel// 2、设置标签显示格式,默认标签位于控件的左侧
void setRowWrapPolicy(RowWrapPolicy policy)    
// policy:标签显示策略,可选值有
//   QFormLayout::DontWrapRows → 标签在控件左侧(默认)
//   QFormLayout::WrapLongRows → 长标签会换行
//   QFormLayout::WrapAllRows → 所有标签显示在控件上方
// 功能:控制表单布局中标签与控件的相对位置

案例:

Widget_04::Widget_04(QWidget *parent) :  // 构造函数,参数 parent 指定父窗口QWidget(parent),                        // 调用 QWidget 的构造函数ui(new Ui::Widget_04)                   // 创建 UI 对象
{ui->setupUi(this);                      // 初始化并加载 Qt Designer 生成的 UI 界面QFormLayout* flayout = new QFormLayout(this); // 创建表单布局管理器,父对象为当前窗口flayout->addRow("姓名", new QLineEdit);      // 添加一行,左侧标签为“姓名”,右侧控件为文本框flayout->addRow("地址", new QLineEdit);      // 添加一行,左侧标签为“地址”,右侧控件为文本框flayout->addRow("邮箱", new QLineEdit);      // 添加一行,左侧标签为“邮箱”,右侧控件为文本框flayout->setSpacing(10);                     // 设置行间距和列间距为 10 像素flayout->setRowWrapPolicy(QFormLayout::WrapAllRows); // 设置表单布局策略:标签全部显示在控件上方,而不是默认的左侧
}
布局类型描述
QFormLayout(表单布局)专门用于“标签 + 控件”形式的表单界面,每行通常是一个标签和一个控件。适合数据录入或设置界面。
QGridLayout(表格布局)类似于二维表格的布局,可以在行和列中放置控件,灵活性更高,不限于标签和控件的组合。
七、QStackedLayout((堆栈布局)

QStackedLayout布局管理器可以容纳多个控件或者窗口,但每次只显示其中的一个,如下:

在这里插入图片描述

在整个窗口布局中左侧使用QListWidget实现,添加3个子项。右侧则使用QStackedLayout存放3个子窗口,通过堆栈布局可以实现窗口间的切换。

常用函数:

// 1、添加控件
int addWidget(QWidget *widget)
// 2、设置显示样式
void setStackingMode(StackingMode stackingMode)

stackingMode:类型是 QStackedLayout::StackingMode 枚举,一般有两个值:

  1. StackOne(默认)
    • 一次只显示一个控件,其他控件隐藏。
    • 典型用法:选项卡切换界面。
  2. StackAll
    • 所有控件都显示在同一位置上(重叠显示)。
    • 很少使用,一般用于特殊重叠效果或自定义动画。

案例:

StackedLayout::StackedLayout(QWidget *parent) :  // 构造函数,初始化父窗口QWidget(parent),                             // 调用父类 QWidget 的构造函数ui(new Ui::StackedLayout)                    // 初始化 UI 指针
{ui->setupUi(this);                            // 设置界面// 水平布局QHBoxLayout* hlayout = new QHBoxLayout(this); // 创建水平布局管理器,并设置为窗口的主布局QListWidget* listWidget = new QListWidget;    // 创建列表控件,用于选择页面listWidget->addItem("窗口一");                 // 添加列表项 "窗口一"listWidget->addItem("窗口二");                 // 添加列表项 "窗口二"listWidget->addItem("窗口三");                 // 添加列表项 "窗口三"hlayout->addWidget(listWidget,1);             // 将列表控件添加到水平布局,占 1 份比例// 堆栈布局QStackedLayout* slayout = new QStackedLayout; // 创建堆栈布局管理器,用于显示多个页面page1* p1= new page1;                         // 创建自定义页面 1Page2* p2= new Page2;                         // 创建自定义页面 2Page3* p3= new Page3;                         // 创建自定义页面 3slayout->addWidget(p1);                       // 将页面 1 添加到堆栈布局slayout->addWidget(p2);                       // 将页面 2 添加到堆栈布局slayout->addWidget(p3);                       // 将页面 3 添加到堆栈布局hlayout->addLayout(slayout,4);               // 将堆栈布局添加到水平布局,占 4 份比例// 连接信号和槽,实现点击列表项切换堆栈布局显示的页面connect(listWidget, &QListWidget::currentRowChanged, slayout, &QStackedLayout::setCurrentIndex);
}
  • QListWidgetQt 提供的一个列表控件(列表视图),继承自 QListView。就是一个 竖着排列、可点击选择的条目列表控件
元素作用
listWidget用户点击的列表,发出当前行索引信号 currentRowChanged(int)
slayout堆栈布局,根据索引显示对应页面,槽函数 setCurrentIndex(int)
connect将信号和槽直接连接,实现点击列表项切换页面
  • 信号发出行索引,槽函数接收索引切换页面,因为参数类型匹配,所以直接连接就能实现“点击左边列表 → 显示右边对应页面”,完全不需要额外写槽函数。

💡为什么不需要显式写槽函数

1. 信号和槽的本质

在 Qt 中:

connect(sender, &Sender::signal, receiver, &Receiver::slot);
  • sender 发出信号
  • receiver 响应信号
  • slot 是槽函数,用来处理信号的逻辑

槽函数可以是自定义的成员函数,也可以是 Qt 自带的公共函数,只要参数类型匹配即可。


2. 参数匹配原则

你的代码是:

connect(listWidget, &QListWidget::currentRowChanged,slayout, &QStackedLayout::setCurrentIndex);
  • 信号:currentRowChanged(int currentRow) → 发出一个 int
  • 槽函数:setCurrentIndex(int index) → 接收一个 int

💡 关键点

Qt 的信号槽机制允许信号直接连接到已有的公共成员函数,只要参数类型匹配即可。

也就是说,你不必写一个自定义槽函数去“取信号的值然后再调用 setCurrentIndex”,因为 Qt 已经帮你把参数传给了 setCurrentIndex

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

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

相关文章

Linux CentOS 安装 .net core 3.1

打开终端,输入以下命令以添加 .NET Core Yum 仓库:sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm安装 .NET Core SDK:sudo yum install dotnet-sdk-3.1验证安装:dotnet --versionre…

深度剖析Spring AI源码(三):ChatClient详解,优雅的流式API设计

深度剖析Spring AI源码(三):ChatClient详解,优雅的流式API设计“The best APIs are those that make simple things simple and complex things possible.” —— Alan Kay (计算机科学巨匠) Spring AI的ChatClient API正是这句话…

C语言基础:(二十五)预处理详解

目录 前言 一、预处理符号 二、#define 定义常量 三、#define 定义宏 四、带有副作用的宏参数 五、宏替换的规则 六、宏函数对比 七、# 和 ## 7.1 #运算符 7.2 ##运算符 八、命名约定 九、#undef 十、命令行定义 十一、条件编译 十二、头文件的包含 12.1 头…

本地文件夹即时变身 Web 服务器(文件服务器)

一:http-server npm install --global http-server 使用,在一个目录下打开 cmd http-server [path] [options] [path] defaults to ./public if the folder exists, and ./ otherwise. 可以下载文件,但是不能下载文件夹。 二:…

Golang云端编程入门指南:前沿框架与技术全景解析

Golang云端编程入门指南:前沿框架与技术全景解析 1 引言:Go语言在云原生时代的优势 Go语言(Golang)由Google开发,凭借其简洁的语法、卓越的并发性能和高效的编译速度,已成为云端应用开发的首选语言之一。…

蓝凌EKP产品:从 XML 到 JSON ——表单存储的性能优化实践

1. 背景介绍蓝凌 EKP 的表单引擎,是整个低代码平台的核心能力之一。它不仅仅是“存储表单”,更是 企业级应用快速构建的基础设施。它支持各种复杂表单配置(字段、布局、校验、权限、联动、子表单)。它能灵活绑定流程,实…

STM32高级定时器-输出比较模式

一.输出比较原理1.输出比较 通过定时器的外部引脚对外输出控制信号,将通道X(x1,2,3,4)通常设置为PWM1、PWM2模式。 2.比较寄存器 当计数器CNT和比较寄存器CCR的值相等时,输出参考信号OCxREF的信号的极性发生改变,其中OCxREF1(高电平)称为有效…

深入理解Unity中的`.meta`文件:以纹理文件为例

在Unity开发中,.meta文件是一个经常被提及但又容易被忽视的组成部分。这些隐藏的元数据文件在项目的稳定性和一致性中扮演着重要角色,尤其是在处理纹理文件时。本文将深入探讨.meta文件的作用、内容、版本控制以及常见问题,帮助开发者更好地理…

【机器学习】3 Generative models for discrete data

本章目录 3 Generative models for discrete data 65 3.1 Introduction 65 3.2 Bayesian concept learning 65 3.2.1 Likelihood 67 3.2.2 Prior 67 3.2.3 Posterior 68 3.2.4 Posterior predictive distribution 71 3.2.5 A more complex prior 72 3.3 The beta-binomial mod…

Gemini CLI 与 MCP 服务器:释放本地工具的强大潜力

前言 Gemini CLI 是一款强大的命令行工具,它将 Google 的 Gemini 模型带入了您的终端。然而,其真正的潜力在于通过 模型上下文协议(Model Context Protocol, MCP) 与外部工具集成。本文将结合两篇关键文章,深入探讨什…

HTTP、HTTPS 与 WebSocket 详解

HTTP、HTTPS 与 WebSocket 详解 在网络通信中,HTTP、HTTPS 和 WebSocket 是三种常见的应用层协议,分别适用于不同的场景。以下从定义、特点、工作原理和适用场景等方面详细解析: 一、HTTP(HyperText Transfer Protocol&#xff0c…

8月21日

#include "head.h"seq_p create_seq() {seq_p S(seq_p)malloc(sizeof(seq_list));if(SNULL){printf("malloc error");return NULL;}memset(S,0,sizeof(seq_list));return S; }//头插 void insert_head(seq_p S,int value,int len) {//判NULLif(SNULL){prin…

视频号存在争议了...

目前实测到:视频号里那套 争议信息提示加AI真相雷达,已经在不少视频下上线了(这是一个非常火爆的趋势!)伙伴们都知道,短视频里的观点来得快、走得也快,很多人看完就转发。你想想看,要…

音视频处理工作室:实时通信的媒体层设计

在开发视频会议、语音聊天等实时通信应用时,媒体层(Media Layer) 是整个系统的核心。它就像是一个专业的"音视频处理工作室",负责从采集声音画面到最终播放的全流程。本文将通过通俗易懂的比喻,解析媒体层中…

读《精益数据分析》:A/B测试与多变量测试

A/B测试与多变量测试:从入门到实战的完整指南 在数据驱动的时代,实验已经成为产品优化和商业决策的核心工具。而在众多实验方法中,A/B测试与多变量测试几乎是每一位产品经理、数据分析师、增长团队绕不开的关键词。 很多人第一次听到它们时&a…

中介者模式及优化

中介者模式(Mediator Pattern)是一种行为型设计模式,其核心思想是通过引入一个“中介者”对象,封装多个对象(称为“同事对象”)之间的复杂交互关系,使同事对象无需直接相互引用,而是…

卷积神经网络的基本概念

卷积神经网络 CNN,即卷积神经网络,是一种深度学习算法,在图像处理,视觉识别等任务中表现出色。 卷积神经网络的组成 CNN模型的组件包括卷积层,池化层,全连接层。 卷积层:提取图像中的局部特征池…

亚远景- 从算法到刹车片:ISO/PAS 8800如何量化自动驾驶的“安全冗余”?

ISO/PAS 8800作为全球首个针对道路车辆人工智能安全的权威标准,通过全生命周期管理框架与量化安全指标,为自动驾驶系统构建了从算法到硬件的“安全冗余”量化体系,其核心逻辑可拆解为以下四层结构:一、数据层:量化训练…

【QT/C++】实例理解类间的六大关系之实现关系(Realization)

【QT/C】实例理解类间的六大关系之实现关系(Realization) 在前面章节讲完了实例理解类间的六大关系之泛化关系,效果不错,获得粉丝的一致好评!!! 接下来,本文我将继续尝试分享并总结…

Coze用户账号设置修改用户头像-后端源码

前言 本文将深入分析Coze Studio项目的用户头像修改功能后端实现,通过源码解读来理解整个头像上传和更新流程的架构设计和技术实现。用户头像修改作为用户个人信息管理系统的重要组成部分,主要负责处理图片文件上传、存储和用户信息更新,提升…