1. QWidget(90 年代)
    传统矩形控件,CPU 光栅,信号槽,最适合桌面原生。
  2. Graphics-View / scene / item(2005+)
    2D 画布,无限缩放/旋转,适合矢量图、编辑器等需要“画”而不是“控件”的场景。
  3. Qt Quick / QML / SceneGraph(2010+)
    GPU 节点树,声明式语法,动画流畅,定位移动端、嵌入式、现代 UI。
  4. Qt Quick 3D / Qt Graphs(2020+)
    在 SceneGraph 上长出来的 3D 赛道,对标 WebGL/Three.js。
  5. Qt WebEngine(2013+)
    直接搬一个 Chromium,用来嵌网页、混合开发。
  6. Qt DataVisualization(2014+)
    OpenGL ES 2 自绘 3D 柱状/曲面,和 Graphics-View 无关。
  7. 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 一样自由:

  1. 绝对坐标
    x: 100; y: 200 —— 同 scene 的 pos,最直白。

  2. 锚系 (anchors) —— 最常用
    anchors.left: parent.left; anchors.margins: 8
    等价于 CSS 的「flex + justify」一行搞定,不写死坐标也能贴边/居中/等距。

  3. 行/列/栅格 (Row/Column/Grid) —— 自动流式
    像 HTML 的 display: flex / grid;元素顺序排布,窗口缩放自动换行/拉伸

  4. 布局管理器 (RowLayout/ColumnLayout/GridLayout) —— 可权重拉伸
    类似 Widget 的 QHBoxLayout;给子项设 Layout.fillWidth: true 就能按比例瓜分空间。

  5. 绑定表达式 —— 布局也响应数据
    width: parent.width * 0.3 + header.height
    任何属性都能是表达式,一行完成响应式

  6. Repeater + 模型 —— 动态生成列表/网格
    类似 HTML 的 v-for / *ngFor;数据变 → 项数自动增减,布局跟模型走

  7. 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这种数据驱动界面元素的应用的核心问题.