Qt界面方案qml死灰复燃
- QWidget(90 年代)
传统矩形控件,CPU 光栅,信号槽,最适合桌面原生。 - Graphics-View / scene / item(2005+)
2D 画布,无限缩放/旋转,适合矢量图、编辑器等需要“画”而不是“控件”的场景。 - Qt Quick / QML / SceneGraph(2010+)
GPU 节点树,声明式语法,动画流畅,定位移动端、嵌入式、现代 UI。 - Qt Quick 3D / Qt Graphs(2020+)
在 SceneGraph 上长出来的 3D 赛道,对标 WebGL/Three.js。 - Qt WebEngine(2013+)
直接搬一个 Chromium,用来嵌网页、混合开发。 - Qt DataVisualization(2014+)
OpenGL ES 2 自绘 3D 柱状/曲面,和 Graphics-View 无关。 - Qt Shader / Qt Quick EffectMaker(2022+)
让你写 Vulkan/GLSL 特效,再往前就是纯 GPU 自绘。 
如果做类似vscode那样的编辑器
- Qt Quick / QML + SceneGraph 是唯一能流畅支撑 VS Code / Zed 级别文本编辑器的赛道;
 - Graphics-View 或 QWidget 都只能做原型**
 
qml死灰复燃???
- 之前姿势错了, 并不是qml去递归数据, 而是把数据平铺为列表, 然后灌给qml….
 
qml的加载
| 维度 | setSource(url) / Loader { source: ... } | 
      import "subdir" 或 import mymodule | 
    
|---|---|---|
| 加载时机 | 运行时动态加载 | 解析时静态加载 | 
| 能否卸载 | 可以(换 source 即销毁) | 不能(一旦 import 常驻) | 
| 对文件名要求 | 无(大小写随意) | 当隐式类型使用时必须首字母大写 | 
| 作用 | 把文件当对象树实例化 | 把文件当类型库引用,然后自己再 MyButton {} | 
    
QML 在海量元素界面(编辑器 / 脑图 / 大型看板)里比 Widgets + View/Scene/Item 快,核心差距不在“语言”而在渲染架构 + 数据通道 + 批量化处理。
1. 渲染管线:Scene Graph VS CPU QPainter
| 维度 | QML (Qt Quick 2+) | Widgets + Graphics View | 
|---|---|---|
| 底层 API | Scene Graph → OpenGL/Vulkan/D3D 批渲染 | QPainter → CPU raster(或单对象 OpenGL) | 
| 线程 | 独立渲染线程;UI 逻辑不阻塞绘制 | 主线程里顺序 paintEvent | 
    
| 批处理 | 自动合并相同材质/图元的一次 draw call | 每个 QGraphicsItem 默认单独调用 paint() → 大量 draw call | 
    
| 实测 1k 动态元素 | 58 fps / CPU 12 % | 32 fps / CPU 28 % | 
结论:Scene Graph 把几千个矩形/图片/曲线合并成几十次 GPU 调用;Graphics View 默认走逐对象 CPU 绘制,draw call 差距 1–2 个数量级。
2. 数据绑定 & 变更粒度
- 
    
QML 的
property+notify机制只精确刷新受影响的节点/绑定表达式;
脑图里拖动一个节点,只有位置绑定 + 相关连线重绘,其余元素帧缓存直接复用。 - 
    
Graphics View 里任何 item 改几何 = 整场景重新索引 + 视图 update()(除非你自己写
boundingRegion优化);
默认策略是“脏矩形合并后整 viewport paint”,粒度粗得多。 
3. 内存与对象模型
- 
    
QML 的 Item 是轻量 JS 对象 + 场景图节点,无 QWidget 的 200+ 字节事件/调色板/字体等包袱;
官方数据:同屏 10 k 个 Item 比 10 k 个 QGraphicsItem 省约 40 % 内存 。 - 
    
支持 Loader / Repeater / Delegate 按需实例化 + 对象池;
Graphics View 没有内建“虚拟化”概念,全部一次性 new 出来。 
4. GPU 加速范围
- 
    
QML 默认就把矩形/图片/文字/矢量路径转成 GPU 纹理/三角形;
甚至贝塞尔曲线也用Shape→ 三角化 → 一次 draw 。 - 
    
Graphics View 除非你把每个 Item 改成
QGraphicsGLWidget或自己写 VBO,否则99 % 场景仍是 CPU 画;
且 OpenGL 路径是“每 item 一次 FBO 切换”,比 Scene Graph 批渲染慢得多 。 
5. 什么时候 Graphics View 反而更快?
- 静态/低变更场景(原理图、GIS 底图)+ 你已写死 GPU 批处理 + 手写 LOD → 可逼近 QML 帧率。
 - 需要像素级自定义绘制(CAD 剖面线、复杂矢量线型)——QPainter 的 CPU 算法更成熟。
 
结论
在海量频繁变动的元素场景下,QML 的  
“Scene Graph 批渲染 + 轻量对象 + 精确绑定 + 独立渲染线程”  
打 Graphics View 的  
“逐对象 CPU 绘制 + 重事件包袱 + 整区刷新”  
属于架构代差,帧率差距可达 2× 以上、CPU 占用差 一半 。  
除非你把 Graphics View 全部改造成 GPU 批处理 + 对象池,否则追不上 QML 的默认性能。
布局
QML 没有“唯一布局官”——它提供一堆定位范式,你按元素性质随时混用,像 HTML 的 flex/grid/absolute coexist 一样自由:
- 
    
绝对坐标
x: 100; y: 200—— 同 scene 的pos,最直白。 - 
    
锚系 (
anchors) —— 最常用
anchors.left: parent.left; anchors.margins: 8
等价于 CSS 的「flex + justify」一行搞定,不写死坐标也能贴边/居中/等距。 - 
    
行/列/栅格 (
Row/Column/Grid) —— 自动流式
像 HTML 的display: flex/grid;元素顺序排布,窗口缩放自动换行/拉伸。 - 
    
布局管理器 (
RowLayout/ColumnLayout/GridLayout) —— 可权重拉伸
类似 Widget 的QHBoxLayout;给子项设Layout.fillWidth: true就能按比例瓜分空间。 - 
    
绑定表达式 —— 布局也响应数据
width: parent.width * 0.3 + header.height
任何属性都能是表达式,一行完成响应式。 - 
    
Repeater + 模型 —— 动态生成列表/网格
类似 HTML 的v-for/*ngFor;数据变 → 项数自动增减,布局跟模型走。 - 
    
Path / Shape 定位 —— 曲线/极坐标
让元素沿着PathQuad/PathArc分布,脑图连线节点常用。 
一句话:  
QML 靠「锚 + 行/列/栅格 + 绝对坐标」三大件就能覆盖 90 % 场景;  
其余是锦上添花,随时混用,比 Widget 的「必须先选 Layout」更自由。
最终结论: qml不值得使用
- 
    
所谓的gpu优势是个幻觉. scene/view架构一样可以高效opengl, qt目前正在废弃opengl接口, 改为自己的一个抽象层.
 - 
    
相比GV架构, qml增加了一个层次, 导致问题复杂化. 写qml时 天然带一个数据结构, 定死的repeater层次结构, 写代码解析数据时, 要兼容这个结构, 而不是直接把数据映射到界面元素, 虽然写GV时, 我是映射为平铺的list结构, 但是, 在GV我可以直接处理这个list, 直接计算pos, 然后一把就布局好了, 但是qml, 我要考虑qml那边的数据结构以及组装之后的数据的格式一致性. 任何界面修改都要改2遍. 这个可能此时他们之间在做vscode/freemind这种数据驱动界面元素的应用的核心问题.