在图形界面开发里,如果控件的位置和大小完全依赖手动坐标,就会有几个明显问题:
- 窗口一旦缩放,界面容易错位。
- 不同系统字体大小不同,控件可能重叠。
- 国际化后文本长度变化,静态坐标很难维护。
- 后期增加控件时,手工调整成本很高。
Qt 的布局管理器就是为了解决这些问题。布局会根据:
- 父窗口尺寸
- 拉伸因子 stretch
- 边距 margins
- 间距 spacing
自动计算每个控件应当占据的区域。
1. 效果演示
本节课要实现的效果,如下:
2. 四种布局说明
水平布局 QHBoxLayout
它会把子控件按照从左到右的顺序排布。
典型场景:顶部工具栏,搜索框和搜索按钮同行展示垂直布局 QVBoxLayout
它会把子控件按照从上到下的顺序排布。
典型场景:页面主内容区,左侧导航栏网格布局 QGridLayout
它按照行和列组织控件。
你可以明确指定一个控件放在第几行、第几列,也可以让它跨多行、多列。
典型场景:图片宫格,计算器布局,需要同时控制横向和纵向关系的界面表单布局 QFormLayout
它是专门为 “标签 + 输入控件” 这种界面设计的。
它本质上是两列结构:左边通常是字段名,右边通常是输入组件。
典型场景:注册表单,登录表单,用户资料编辑页
3. 从零实现
3.1 新建项目
新建一个名为LayoutDemo的项目,如下:
3.2 界面布局
接下来开始拖放控件,完成界面布局:
- 整体采用栅格布局:右侧的 “栅格布局” 占据第0行,“表单布局” 占据第1行,左侧的 “水平布局” 占据两行
- “栅格布局” 中:选中所有控件,将它们的 “Horizontal Policy” 和 “Vertical Policy” 都设置为 “Expanding”
- “表单布局” 中:为
cboRole添加了三个条目-研发、销售、财务 - 修改textEdit样式表:
QTextEdit { color: #0080ce; }

3.3 显示边距、间距、控件宽度
在Qt(以及一般的UI设计中),边距(Margin)和间距(Spacing)是两个经常被混淆但概念完全不同的属性。简单来说:
- 边距(Margin) 是控件与其父容器或布局与父容器之间的空白距离。
- 间距(Spacing) 是布局内相邻子控件之间的空白距离。
接下来,实现当窗口缩放时,实时查看水平布局中 “horizontalWidget” 的边距和间距,以及4个按钮的宽度
首先,选中左侧的 “horizontalWidget”,然后在右侧的属性窗口中修改起布局参数:
然后,来到mywidget.h中,声明基类的事件处理函数
class Widget : public QWidget
{
protected:
// 事件处理函数,用于响应窗口或控件的大小变化
void resizeEvent(QResizeEvent *event) override;
};
最后,来到mywidget.cpp中,实现resizeEvent,如下:
void Widget::resizeEvent(QResizeEvent *event) {
static int index = 1;
int lineCnt = ui->textEdit->document()->lineCount();
if (lineCnt > 100 * 6) {
ui->textEdit->clear();
index = 1;
}
// 索引
QString strIndex = QString("[%1]------------").arg(index++, 3, 10, QChar('0'));
// 按钮宽度
QString width = QString("按钮宽度:\t%1,%2,%3,%4")
.arg(ui->btnAdd->width())
.arg(ui->btnDelete->width())
.arg(ui->btnModify->width())
.arg(ui->btnQuery->width());
// 边距
QMargins margins = ui->horizontalWidget->layout()->contentsMargins();
QString strMargins = QString("边距(左上右下):\t%1,%2,%3,%4")
.arg(margins.left())
.arg(margins.top())
.arg(margins.right())
.arg(margins.bottom());
// 间距
int spacing = ui->horizontalWidget->layout()->spacing();
QString strSpacing = QString("间距:\t\t%1").arg(spacing);
ui->textEdit->append(strIndex);
ui->textEdit->append(width);
ui->textEdit->append(strMargins);
ui->textEdit->append(strSpacing);
ui->textEdit->append("------------------");
ui->textEdit->append("");
// 移动光标到最后一行
ui->textEdit->moveCursor(QTextCursor::End);
}
此时,运行可以看到前两个按钮拉伸因子为0,因此不会拉伸,后两个按钮会按比例分配剩余空间
4. 点赞、获取源码
看到这里的小伙伴,去B站给明王一个【免费的点赞】吧,你的支持,是我持续更新优质内容的动力,感谢~
源码下载地址
链接: https://pan.baidu.com/s/1lME_Tgn8zneZmZpWiKwh-Q
提取码: ming







