【Qt开发】布局管理器(三)-> QGridLayout 网格布局
文章目录
- 1 -> 概述
- 2 -> 核心属性
- 3 -> 核心特性详解
- 3.1 -> 网格化布局结构
- 3.2 -> 灵活的控件放置机制
- 3.3 -> 多样化的对齐方式
- 4 -> 使用优势深度分析
- 4.1 -> 卓越的界面一致性维护
- 4.2 -> 智能的自动调整能力
- 4.3 -> 高效的空间利用率
- 5 -> 布局策略与配置选项
- 5.1 -> 行与列的精细控制
- 5.2 -> 间距与边距管理
- 6 -> 代码示例
- 6.1 -> 使用 QGridLayout 管理元素
- 6.2 -> 设置 QGridLayout 中元素的大小比例
- 6.3 -> 设置垂直方向的拉伸系数
- 7 -> 总结

1 -> 概述
QGridLayout是Qt框架中一个极其强大且灵活的布局管理器,它采用网格状的结构来组织和排列用户界面中的各种控件部件。与传统的线性布局管理器相比,QGridLayout突破了单一维度的限制,提供了真正意义上的二维布局能力。这种布局方式使得开发者能够以更加精细和直观的方式来设计复杂的用户界面,满足现代应用程序对界面布局的多样化需求。
在Qt的布局管理器体系中,QGridLayout占据着重要的地位。它不仅仅是一个简单的网格容器,更是一个智能的布局管理系统,能够根据内容的变化和容器尺寸的调整自动优化布局结构,同时保持界面元素之间的相对关系和视觉一致性。
2 -> 核心属性
整体和 QVBoxLayout 以及 QHBoxLayout 相似。但是设置 spacing 的时候是按照垂直和水平两个方向来设置的。
| 属性 | 说明 |
|---|---|
| layoutLeftMargin | 左侧边距 |
| layoutRightMargin | 右侧边距 |
| layoutTopMargin | 上方边距 |
| layoutBottomMargin | 下方边距 |
| layoutHorizontalSpacing | 相邻元素之间水平方向的间距 |
| layoutVerticalSpacing | 相邻元素之间垂直方向的间距 |
| layoutRowStretch | 行方向的拉伸系数 |
| layoutColumnStretch | 列方向的拉伸系数 |
3 -> 核心特性详解
3.1 -> 网格化布局结构
QGridLayout最基本的特征就是其网格化的布局结构。它将可用的布局空间划分为若干个虚拟的网格单元,这些网格单元按照行和列的方式进行组织,形成一个规整的二维矩阵。每个网格单元都可以容纳一个控件部件,或者作为更大控件所占区域的组成部分。
这种网格结构的设计理念源于人们对规整、有序布局的自然倾向。在实际应用中,这种结构使得界面元素的排列变得可预测和易于管理。开发者可以像在表格中定位单元格一样,精确地指定每个控件在网格中的位置,从而创建出结构清晰、排列整齐的用户界面。
3.2 -> 灵活的控件放置机制
QGridLayout在控件放置方面提供了极大的灵活性,这是它区别于其他简单布局管理器的重要特征。
精确定位功能允许开发者将控件放置在网格的特定行和列交叉点上。通过指定具体的行索引和列索引,可以确保每个控件都出现在设计者期望的位置上。这种精确的定位能力为创建复杂界面布局奠定了基础。
跨行跨列支持是QGridLayout的一个突出特性。控件不仅可以占据单个网格单元,还可以横向跨越多个列或者纵向跨越多个行。这种跨越能力使得QGridLayout能够适应不同大小和比例的控件,为创建非规则布局提供了可能。例如,一个标题控件可以横跨整个顶部区域,而侧边栏控件则可以纵向跨越多个行。
动态尺寸适应机制确保了布局能够根据内容需求和可用空间的变化进行智能调整。当控件内容发生变化时,其所在的网格单元会自动调整尺寸以适应新的内容要求。同时,当整个布局容器的尺寸改变时,网格中的各个单元会按照预设的拉伸因子和大小策略进行相应的调整,保持整体布局的协调性和可用性。
3.3 -> 多样化的对齐方式
在QGridLayout中,每个控件在其所在的网格单元内都可以独立设置对齐方式,这为界面微调提供了精细的控制手段。
水平对齐选项包括左对齐、居中对齐和右对齐,适用于控制控件在水平方向上的位置。不同类型的控件可以根据其功能和使用习惯选择最合适的对齐方式。例如,文本标签通常采用左对齐,而按钮则可能更适合居中对齐。
垂直对齐选项包括顶部对齐、居中对齐和底部对齐,用于控制控件在垂直方向上的位置。这种对齐方式的灵活性在处理不同高度的控件时显得尤为重要,可以确保它们在视觉上保持协调的统一感。
对齐方式的合理运用不仅提升了界面的美观度,还增强了用户的交互体验。一致的对齐方式可以建立视觉引导线,帮助用户更快地理解和操作界面。
4 -> 使用优势深度分析
4.1 -> 卓越的界面一致性维护
在跨平台应用程序开发中,界面一致性是一个重要的挑战。不同的操作系统、不同的屏幕分辨率、不同的字体渲染方式都可能导致界面显示的差异。QGridLayout通过其智能的布局算法,有效地缓解了这些问题。
它确保在不同平台上,界面元素的相对位置和大小关系保持一致。无论是Windows、macOS还是Linux系统,使用QGridLayout管理的界面都能够保持设计时的基本结构和比例关系。这种一致性大大减少了跨平台适配的工作量,提高了开发效率。
4.2 -> 智能的自动调整能力
现代应用程序需要适应各种不同的使用环境和用户偏好。窗口大小可能被用户随意调整,系统字体大小可能被修改,显示比例因子可能各不相同。QGridLayout的自动调整能力使得应用程序能够优雅地应对这些变化。
当父窗口的尺寸发生变化时,QGridLayout会自动重新计算各个网格单元的尺寸和位置,确保布局的整体结构不被破坏。它会根据预先设置的拉伸因子、大小约束和尺寸策略,智能地分配可用空间,优先保证重要内容的可见性和可操作性。
这种响应式的布局特性使得应用程序能够适应从移动设备到桌面显示器等各种尺寸的屏幕,为用户提供一致的体验。
4.3 -> 高效的空间利用率
通过合理的网格划分和控件排列,QGridLayout能够实现极高的空间利用率。它消除了手工布局中常见的空白区域浪费问题,使得有限的屏幕空间能够得到最大程度的利用。
网格系统的规整性使得控件可以紧密而有序地排列,既保持了视觉上的清晰度,又实现了空间的经济性。这种特性在开发需要显示大量信息的应用程序时显得尤为重要,如数据分析工具、监控系统等。
5 -> 布局策略与配置选项
5.1 -> 行与列的精细控制
QGridLayout提供了对行和列属性的精细控制能力,这使得开发者可以根据具体需求定制布局行为。
尺寸策略设置允许为每一行和每一列定义其大小调整行为。可以设置最小尺寸、首选尺寸和最大尺寸,确保布局在各种情况下都能保持良好的视觉效果。例如,可以确保某些关键列不会因为空间不足而变得过窄,影响内容的可读性。
拉伸因子配置是控制布局弹性的重要工具。通过为不同的行和列分配合适的拉伸因子,可以指定当额外空间可用时,哪些部分应该获得更多的空间分配。同样,当空间不足时,拉伸因子也决定了哪些部分应该优先被压缩。
5.2 -> 间距与边距管理
合理的间距设计对于创建视觉舒适的界面至关重要。QGridLayout提供了全面的间距控制机制。
行列间距设置允许独立控制水平间距和垂直间距。这些间距值决定了相邻网格单元之间的空白区域大小。适当的间距可以在界面元素之间建立清晰的视觉分离,提高可读性和可操作性。
内容边距管理用于控制布局内容与容器边缘之间的距离。通过设置上、下、左、右四个方向的边距,可以确保内容不会紧贴容器边缘,提供舒适的视觉呼吸空间。边距的设置需要考虑整体视觉平衡和特定平台的界面指南。
6 -> 代码示例
6.1 -> 使用 QGridLayout 管理元素
- 在代码中创建 QGridLayout 和四个按钮
- 使用 addWidget 添加控件到布局管理器中。但是添加的同时会指定两个坐标。表示放在第几行,第几列。
#include "widget.h"
#include "ui_widget.h"#include <QPushButton>
#include <QGridLayout>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button1 = new QPushButton("按钮1");QPushButton* button2 = new QPushButton("按钮2");QPushButton* button3 = new QPushButton("按钮3");QPushButton* button4 = new QPushButton("按钮4");QGridLayout* layout = new QGridLayout();layout->addWidget(button1, 0, 0);layout->addWidget(button2, 0, 1);layout->addWidget(button3, 1, 0);layout->addWidget(button4, 1, 1);// 相当于水平布局管理器
// layout->addWidget(button1, 0, 0);
// layout->addWidget(button2, 0, 1);
// layout->addWidget(button3, 0, 2);
// layout->addWidget(button4, 0, 3);// 相当于垂直布局管理器
// layout->addWidget(button1, 0, 0);
// layout->addWidget(button2, 1, 0);
// layout->addWidget(button3, 2, 0);
// layout->addWidget(button4, 3, 0);// 每个按钮独占一行
// layout->addWidget(button1, 0, 0);
// layout->addWidget(button2, 1, 1);
// layout->addWidget(button3, 2, 2);
// layout->addWidget(button4, 3, 3);this->setLayout(layout);
}Widget::~Widget()
{delete ui;
}
- 执行代码,观察效果,可以看到当前的几个按钮是按照 2 行 2 列的方式排列的。

3. 如果调整行列坐标为下列代码
#include "widget.h"
#include "ui_widget.h"#include <QPushButton>
#include <QGridLayout>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button1 = new QPushButton("按钮1");QPushButton* button2 = new QPushButton("按钮2");QPushButton* button3 = new QPushButton("按钮3");QPushButton* button4 = new QPushButton("按钮4");QGridLayout* layout = new QGridLayout();
// layout->addWidget(button1, 0, 0);
// layout->addWidget(button2, 0, 1);
// layout->addWidget(button3, 1, 0);
// layout->addWidget(button4, 1, 1);// 相当于水平布局管理器layout->addWidget(button1, 0, 0);layout->addWidget(button2, 0, 1);layout->addWidget(button3, 0, 2);layout->addWidget(button4, 0, 3);// 相当于垂直布局管理器
// layout->addWidget(button1, 0, 0);
// layout->addWidget(button2, 1, 0);
// layout->addWidget(button3, 2, 0);
// layout->addWidget(button4, 3, 0);// 每个按钮独占一行
// layout->addWidget(button1, 0, 0);
// layout->addWidget(button2, 1, 1);
// layout->addWidget(button3, 2, 2);
// layout->addWidget(button4, 3, 3);this->setLayout(layout);
}Widget::~Widget()
{delete ui;
}
执行代码,可以看到这几个按钮都在同一行了。相当于 QHBoxLayout

4. 如果调整行列坐标为下列代码
#include "widget.h"
#include "ui_widget.h"#include <QPushButton>
#include <QGridLayout>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button1 = new QPushButton("按钮1");QPushButton* button2 = new QPushButton("按钮2");QPushButton* button3 = new QPushButton("按钮3");QPushButton* button4 = new QPushButton("按钮4");QGridLayout* layout = new QGridLayout();
// layout->addWidget(button1, 0, 0);
// layout->addWidget(button2, 0, 1);
// layout->addWidget(button3, 1, 0);
// layout->addWidget(button4, 1, 1);// 相当于水平布局管理器
// layout->addWidget(button1, 0, 0);
// layout->addWidget(button2, 0, 1);
// layout->addWidget(button3, 0, 2);
// layout->addWidget(button4, 0, 3);// 相当于垂直布局管理器layout->addWidget(button1, 0, 0);layout->addWidget(button2, 1, 0);layout->addWidget(button3, 2, 0);layout->addWidget(button4, 3, 0);// 每个按钮独占一行
// layout->addWidget(button1, 0, 0);
// layout->addWidget(button2, 1, 1);
// layout->addWidget(button3, 2, 2);
// layout->addWidget(button4, 3, 3);this->setLayout(layout);
}Widget::~Widget()
{delete ui;
}
执行代码,可以看到这几个按钮都在同一列了。相当于 QVBoxLayout

- 任意调整行列,即可看到不同的效果。
#include "widget.h"
#include "ui_widget.h"#include <QPushButton>
#include <QGridLayout>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button1 = new QPushButton("按钮1");QPushButton* button2 = new QPushButton("按钮2");QPushButton* button3 = new QPushButton("按钮3");QPushButton* button4 = new QPushButton("按钮4");QGridLayout* layout = new QGridLayout();
// layout->addWidget(button1, 0, 0);
// layout->addWidget(button2, 0, 1);
// layout->addWidget(button3, 1, 0);
// layout->addWidget(button4, 1, 1);// 相当于水平布局管理器
// layout->addWidget(button1, 0, 0);
// layout->addWidget(button2, 0, 1);
// layout->addWidget(button3, 0, 2);
// layout->addWidget(button4, 0, 3);// 相当于垂直布局管理器
// layout->addWidget(button1, 0, 0);
// layout->addWidget(button2, 1, 0);
// layout->addWidget(button3, 2, 0);
// layout->addWidget(button4, 3, 0);// 每个按钮独占一行layout->addWidget(button1, 0, 0);layout->addWidget(button2, 1, 1);layout->addWidget(button3, 2, 2);layout->addWidget(button4, 3, 3);this->setLayout(layout);
}Widget::~Widget()
{delete ui;
}

6.2 -> 设置 QGridLayout 中元素的大小比例
- 创建 6 个按钮,按照 2 行 3 列 的方式排列
- 使用 setColumnStretch 设置每一列的拉伸系数。
#include "widget.h"
#include "ui_widget.h"#include <QPushButton>
#include <QGridLayout>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button1 = new QPushButton("按钮1");QPushButton* button2 = new QPushButton("按钮2");QPushButton* button3 = new QPushButton("按钮3");QPushButton* button4 = new QPushButton("按钮4");QPushButton* button5 = new QPushButton("按钮5");QPushButton* button6 = new QPushButton("按钮6");QGridLayout* layout = new QGridLayout();layout->addWidget(button1, 0, 0);layout->addWidget(button2, 0, 1);layout->addWidget(button3, 0, 2);layout->addWidget(button4, 1, 0);layout->addWidget(button5, 1, 1);layout->addWidget(button6, 1, 2);this->setLayout(layout);// 设置水平拉伸系数layout->setColumnStretch(0, 1);layout->setColumnStretch(1, 2);layout->setColumnStretch(2, 3);
}Widget::~Widget()
{delete ui;
}

另外,QGridLayout 也提供了 setRowStretch 设置行之间的拉伸系数。
上述案例中,直接设置 setRowStretch 效果不明显,因为每个按钮的高度都是固定的。需要把按钮的垂直方向的 sizePolicy 属性设置为 QSizePolicy::Expanding 尽可能填充满布局管理器,才能看到效果。
6.3 -> 设置垂直方向的拉伸系数
- 编写代码,创建 6 个按钮,按照 3 行 2 列方式排列。
使用 setSizePolicy 设置按钮的尺寸策略。可选的值如下:
- QSizePolicy::Ignored:忽略控件的尺寸,不对布局产生影响。
- QSizePolicy::Minimum:控件的最小尺寸为固定值,布局时不会超过该值。
- QSizePolicy::Maximum:控件的最大尺寸为固定值,布局时不会小于该值。
- QSizePolicy::Preferred:控件的理想尺寸为固定值,布局时会尽量接近该值。
- QSizePolicy::Expanding:控件的尺寸可以根据空间调整,尽可能占据更多空间。
- QSizePolicy::Shrinking:控件的尺寸可以根据空间调整,尽可能缩小以适应空间。
#include "widget.h"
#include "ui_widget.h"#include <QPushButton>
#include <QGridLayout>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QPushButton* button1 = new QPushButton("按钮1");QPushButton* button2 = new QPushButton("按钮2");QPushButton* button3 = new QPushButton("按钮3");QPushButton* button4 = new QPushButton("按钮4");QPushButton* button5 = new QPushButton("按钮5");QPushButton* button6 = new QPushButton("按钮6");button1->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);button2->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);button3->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);button4->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);button5->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);button6->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);QGridLayout* layout = new QGridLayout();layout->addWidget(button1, 0, 0);layout->addWidget(button2, 0, 1);layout->addWidget(button3, 1, 0);layout->addWidget(button4, 1, 1);layout->addWidget(button5, 2, 0);layout->addWidget(button6, 2, 1);this->setLayout(layout);// 设置拉伸系数layout->setRowStretch(0, 1);layout->setRowStretch(1, 2);layout->setRowStretch(2, 3);}Widget::~Widget()
{delete ui;
}
- 执行代码,观察效果。
此时的按钮垂直方向都舒展开了。并且调整窗口尺寸,也会按照设定的比例同步变化。

7 -> 总结
QGridLayout作为Qt布局系统中最强大、最灵活的布局管理器,为开发者提供了创建复杂、专业级用户界面所需的一切工具。其网格化的布局理念既符合人们对有序结构的自然认知,又提供了足够的灵活性来应对各种复杂的布局需求。
通过精确的控件定位、跨行跨列的支持、智能的尺寸调整和细致的对齐控制,QGridLayout使得开发者能够以声明式的方式描述界面布局,而无需关心底层复杂的计算和调整逻辑。这种抽象大大提高了开发效率,降低了维护成本。
掌握QGridLayout的有效使用,不仅意味着能够创建出视觉上吸引人的用户界面,更重要的是能够构建出在不同平台、不同环境下都能保持稳定表现和良好用户体验的应用程序。它是每个Qt开发者工具箱中不可或缺的重要工具,值得深入学习和熟练运用。
感谢各位大佬支持!!!
互三啦!!!
