Qt UI布局
Qt UI布局笔记
一、Qt四种布局管理器
| 布局 | 类名 | 用途 | 特点 |
|---|---|---|---|
| 垂直布局 | QVBoxLayout | 控件从上往下排列 | 一列纵向摆放 |
| 水平布局 | QHBoxLayout | 控件从左往右排列 | 一行横向摆放 |
| 网格布局 | QGridLayout | 多行多列表格布局 | 任意行列,复杂界面 |
| 表单布局 | QFormLayout | 标签+输入框成对表单 | 左列Label,右列输入组件,标签自动对齐,登录注册首选 |
核心概念:
- 控件交给布局管理后,不要手动设置
setGeometry(),位置大小全部由布局自动控制。- Spacer(弹簧,蓝色虚线):仅在布局内部生效,用来做留白、居中、挤压控件。
- 没有布局的控件:使用绝对坐标,窗口缩放时控件位置大小不会跟随变化。
常见踩坑
-
每一行单独套
QHBoxLayout水平布局做表单:
每一行互相独立,标签宽度无法统一,输入框会直接铺满整行窗口,就是你用户名密码遇到的问题。
✅ 正确做法:多行标签+输入框一次性全部选中,直接套QFormLayout表单布局。 -
Break Layout(打碎布局):
修改布局出错时,右键 → Lay out → Break Layout,打散现有布局,重新选择布局类型。 -
最外层必须套布局:
整个Dialog/Widget最外层套一层QVBoxLayout垂直布局,整体窗口缩放全部控件自适应。
登录对话框正确层级结构(QDialog)
Login : QDialog
└── 最外层 QVBoxLayout(垂直布局)
├─ 标题Label:登录
├─ QFormLayout 表单布局(用户名、密码两行)
├─ QHBoxLayout 水平布局:角色标签 + RadioButton(服务端) + RadioButton(客户端)
├─ QHBoxLayout 水平布局:水平弹簧 + CheckBox记住密码 + 水平弹簧
└─ QHBoxLayout 水平布局:水平弹簧 + 登录按钮 + 关闭按钮 + 水平弹簧
二、QDialog模态对话框 exec()
QDialog对话框,exec()是模态阻塞调用,会阻塞当前代码执行,对话框关闭之后代码才往下走。
main.cpp示例代码
#include "mainwindow.h"
#include "login.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Login login;
// exec():模态,阻塞!弹出登录框,等待登录框关闭才往下执行
login.exec();
// 登录对话框关闭之后,才创建主窗口
MainWindow w;
w.show();
return QApplication::exec();
}
关键知识点
login.exec():模态阻塞,代码停在这里,用户关闭登录对话框,函数才返回,继续执行后面创建MainWindow。- 区分:
dialog.exec():模态,阻塞,弹出对话框,卡住后面代码(登录弹窗场景)dialog.show():非模态,不阻塞,代码立刻继续往下跑,不会等待窗口关闭。
面试高频:exec() 和 show() 的区别
exec():仅QDialog拥有,模态阻塞,事件循环嵌套,窗口关闭返回int值(accept/reject)。show():所有QWidget都可以调用,非模态,调用之后立刻返回,代码继续执行。
对话框返回值
login.exec();
// 点击确定按钮:返回 QDialog::Accepted
// 点击关闭按钮/右上角叉号:返回 QDialog::Rejected
可以判断登录结果:
Login login;
int ret = login.exec();
if(ret == QDialog::Accepted)
{
// 用户点登录,打开主窗口
MainWindow w;
w.show();
return QApplication::exec();
}
else
{
// 用户点关闭,直接退出程序
return 0;
}
三、面试背诵要点
- Spacer弹簧只有放在布局内部才生效。
exec()是QDialog模态阻塞,窗口关闭代码才继续运行;show()非模态不阻塞。- 布局管理的控件,不要手动调用setGeometry。
- 窗口想要自适应缩放,必须给顶层控件套最外层布局。
浙公网安备 33010602011771号