当前位置: 首页 > news >正文

Qt 布局引擎

Qt Widgets 布局引擎完整结构图 + 算法流程图 + 对比 WPF 心智模型


一、Qt 布局系统整体架构图

我们从最上层开始。


🧱 Qt Widgets 布局引擎结构图

┌────────────────────────────────────────────┐
│                QWidget                     │
│  (窗口 / 控件)                              │
└────────────────────────────────────────────┘│▼
┌────────────────────────────────────────────┐
│               QLayout                      │
│  ├─ QVBoxLayout                            │
│  ├─ QHBoxLayout                            │
│  ├─ QGridLayout                            │
│  ├─ QFormLayout                            │
└────────────────────────────────────────────┘│▼
┌────────────────────────────────────────────┐
│             QLayoutItem                    │
│  (抽象层:所有子项统一接口)                 │
│                                            │
│  ├─ QWidgetItem   (包装 QWidget)          │
│  ├─ QSpacerItem   (弹簧空间)                │
│  └─ 子 Layout (嵌套布局)                    │
└────────────────────────────────────────────┘│▼
┌────────────────────────────────────────────┐
│           QSizePolicy + sizeHint           │
│                                            │
│  控件报告:                                 │
│   - 最小尺寸                                 │
│   - 建议尺寸                                 │
│   - 是否可扩展                               │
└────────────────────────────────────────────┘│▼
┌────────────────────────────────────────────┐
│          几何计算 (setGeometry)             │
│                                            │
│  Layout 分配每个子控件最终 Rect              │
└────────────────────────────────────────────┘│▼
┌────────────────────────────────────────────┐
│               paintEvent                    │
│               最终绘制                       │
└────────────────────────────────────────────┘

二、Qt 布局的核心哲学

Qt 不使用绝对坐标。

它使用:

sizeHint() + QSizePolicy → 布局计算 → setGeometry()

这和 WPF 很像:

Measure → Arrange → Render

三、Qt 布局完整算法流程图(重点)

我们画完整执行流程。


🎯 假设窗口尺寸变化

用户拖动窗口│▼
QWidget::resizeEvent()│▼
QLayout::activate()│▼
QLayout 开始遍历所有 QLayoutItem│▼
调用每个子控件:sizeHint()minimumSizeHint()sizePolicy()│▼
根据算法计算:每个子控件应该分配多少空间│▼
调用:setGeometry(QRect)│▼
每个 QWidget 更新自身尺寸│▼
触发 paintEvent()

四、sizeHint 是什么?

这是 Qt 布局的核心。

每个控件都会说:

QSize QWidget::sizeHint() const

例如:

QSize QPushButton::sizeHint()

它会根据:

  • 字体
  • 文本长度
  • 内边距

算出“理想大小”。


五、QSizePolicy 决定“是否可扩展”

这是 Qt 布局的灵魂。


QSizePolicy 枚举

QSizePolicy::Fixed
QSizePolicy::Minimum
QSizePolicy::Maximum
QSizePolicy::Preferred
QSizePolicy::Expanding
QSizePolicy::MinimumExpanding
QSizePolicy::Ignored

举例

btn->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Fixed
);

含义:

  • 水平方向可扩展
  • 垂直方向固定

六、QVBoxLayout 的内部算法(简化版)

假设有 3 个控件:

[ A ]
[ B ]
[ C ]

算法步骤:


① 收集信息

A sizeHint = 100x30
B sizeHint = 100x40
C sizeHint = 100x50

② 计算总最小高度

30 + 40 + 50 + spacing

③ 如果父窗口更大

剩余空间分配给:

  • Expanding 控件
  • 或 stretch 因子

七、Stretch 因子机制

例如:

layout->addWidget(btn1, 1);
layout->addWidget(btn2, 2);

代表:

剩余空间 1:2 分配

八、嵌套布局结构图

Qt 可以无限嵌套:

QWidget└─ QVBoxLayout├─ QHBoxLayout│    ├─ Button│    └─ Button└─ QGridLayout├─ Label└─ LineEdit

每层都是 QLayoutItem。


九、和 WPF 的对比结构图


WPF

Visual Tree↓
Measure()↓
Arrange()↓
Render()

Qt

QWidget Tree↓
QLayout↓
sizeHint()↓
QSizePolicy↓
setGeometry()↓
paintEvent()

十、真正的内部调用链

内部类关系(简化):

QWidget↓
QWidgetPrivate↓
QLayout↓
QLayoutPrivate↓
QLayoutItem↓
QWidgetItem

布局计算主要在:

QLayout::setGeometry()

十一、为什么 Qt 不会 DPI 崩?

因为:

  • sizeHint 使用逻辑像素
  • 字体尺寸是 DPI aware
  • 布局是动态计算

没有硬编码像素。


十二、你必须掌握的 5 个关键点

如果你想快速通关 Qt 布局:


🔥 1️⃣ 永远不要 setGeometry 手动定位


🔥 2️⃣ 熟练 QSizePolicy

这是最重要的。


🔥 3️⃣ 熟练 Stretch


🔥 4️⃣ 理解 sizeHint


🔥 5️⃣ 熟练嵌套 Layout


十三、工程级建议(结合你背景)

做数据可视化:

不要用 QWidget + 手写像素布局。

建议:

  • 主界面用 QMainWindow
  • 中央区域放 QSplitter
  • 曲线区域用 QOpenGLWidget
  • 周边用 QDockWidget

十四、终极理解一句话

Qt 布局 = 控件自己报需求 + Layout 统一分配空间

而不是:

父容器强制指定坐标


http://www.jsqmd.com/news/418274/

相关文章:

  • 【关于虚拟无电池与充电保护两种模式的理解】
  • 扫描线优化 DP 与单调队列优化 DP
  • 网易云音乐数据分析系统 | Flask+Echarts+Python爬虫+HTML可视化分析 毕业设计源码 深度学习 大数据 人工智能
  • Vite 生产构建(Rollup)深度解析
  • 音乐信息可视化推荐系统 | Python+Flask+Vue+Scrapy+LSTM+Echarts 大数据 人工智能 deepseek 深度学习 毕业设计源码
  • WinRAR解压的临时文件藏在哪?一文告诉你默认路径与查看方法
  • 六氟化硫气体检测仪在电力生产端的预防性应用 - 资讯焦点
  • 用pytorch来自动求导
  • 网易云音乐信息采集可视化分析系统 | 技术栈Flask+Echarts 多模块全流程实现 毕业设计源码 deepseek 人工智能 深度学习
  • ue 日志等级
  • 泓动数据各地区官方联系方式,如何联系到泓动数据咨询GEO业务 - 资讯焦点
  • 需要学习的东西
  • pycharm 启动关闭flask 关闭test
  • IEXS盈十证券:距活动结束仅剩半月,10倍收益加成与特斯拉豪礼静待最后赢家 - 资讯焦点
  • 【AI+教育】用飞书多维表格,零门槛实现教学内容自动化
  • 2026年昆山离婚律师专业甄选推荐:从资质到案例的全方位实用指南 - 资讯焦点
  • 从SEO到GEO: 一位百度前算法工程师的十五年探索 - 资讯焦点
  • 【项目实战】VSCode 里 Git 怎么提交空文件夹?超简单教程
  • 使用 IDEA 插件 JarEditor 修改 JAR 文件,无需手动解压重打包
  • 罗小军拆解AI“黑箱”:生成式引擎挑选答案的四步机制 - 资讯焦点
  • 上海正品兔宝宝全屋定制购买指南:源头工厂选择核心攻略 - 资讯焦点
  • 上海嘉定博园路全屋定制工厂怎么选?靠谱选择指南 - 资讯焦点
  • 吉舍吉屋定制工厂:以“快、真、新”重塑长三角高端定制家居代工新标杆 - 资讯焦点
  • 带指针的结构体-链表节点-随笔
  • 2026年2月液压货梯实力品牌,自动化升降控制技术深度解析 - 品牌鉴赏师
  • 系分/架构——案例之可行性分析
  • 还在手撸提示词?向量引擎+Flux才是AI绘画的终极外挂,画师看完都沉默了...
  • 系分/架构——领域驱动设计之战略设计
  • 基于深度学习的YOLOv8木材缺陷检测系统 deepseek可定制 木材死结木材裂缝图像识别(数据集+模型+jpyqy界面)
  • 单片机基础知识 -- 普通推挽和复用推挽模式