目录1.Qt的界面开发模式1.1.传统 QtWidgetsC 控件默认是 CPU 软件光栅化2.Qt QuickQML 界面与 OpenGL 深度绑定但 Qt6 已解耦2.实现原理2.1.整体分层2.2.核心继承关系2.3.核心组合与依赖关系2.4.Windows 平台 QtWidgets 完整渲染调用链路3.QOpenGLWidget 中使用 QPainter 进行 GPU 加速 2D 绘制4.Qt RHI 渲染架构4.1.诞生背景4.2.分层架构4.3.支持的图形后端4.4.核心渲染流程与关键类4.5.RHI 在 Qt 各模块中的应用4.6.选型建议1.Qt的界面开发模式1.1.传统 QtWidgetsC 控件默认是 CPU 软件光栅化我们日常使用的QWidget、QPushButton、QTableView等标准控件采用自绘机制默认走CPU 软件光栅化不依赖 OpenGL。1.底层绘制流程Qt 对外提供统一的 2D 绘制 APIQPainter所有控件的外观都通过QPainter描述QPainter底层由不同的Paint Engine绘制引擎真正执行光栅化计算默认引擎QRasterPaintEngine纯 CPU 软件光栅化跨平台行为一致兼容性最好。绘制完成后最终将像素结果输出到操作系统的窗口表面Windows输出到 GDI 设备上下文HDCLinux X11/Wayland输出到 XCB / Wayland 可绘表面macOS输出到 Core GraphicsQuartz上下文这也是 QtWidgets 能做到跨平台样式一致的核心原因控件外观是 Qt 自己绘制的而非调用系统原生控件。2.QtWidgets 与 OpenGL 的结合方式OpenGL 不是 QtWidgets 的默认渲染路径但可以按需开启常见有三种用法局部嵌入 OpenGL 内容使用QOpenGLWidget控件在其中直接调用 OpenGL API 绘制 3D 场景、可视化图形等这是 Qt 项目中最常用的 OpenGL 集成方式。QPainter 走 GPU 加速通过QOpenGLPaintDevice将QPainter绑定到 OpenGL 上下文让原本 CPU 执行的 2D 绘制指令转由 GPU 完成适合大量图元的高性能绘制场景。全局 OpenGL 窗口合成Qt5 可通过Qt::AA_UseOpenGLES/Qt::AA_UseDesktopOpenGL等全局属性让整个 Widget 窗口基于 OpenGL 表面渲染。但该方式兼容性问题较多实际桌面项目很少全局开启。2.Qt QuickQML 界面与 OpenGL 深度绑定但 Qt6 已解耦Qt Quick 是 Qt 新一代声明式 UI 框架基于场景图Scene Graph渲染从诞生起就依赖 GPU 硬件加速。1.Qt5 时代默认直接基于 OpenGLQt 5.x 版本中Qt Quick 2 的场景图默认直接基于 OpenGL / OpenGL ES 2.0 实现所有界面元素都会被转换成 OpenGL 渲染指令由 GPU 绘制 —— 这也是很多人 “Qt 用 OpenGL 画界面” 印象的主要来源。2.Qt6 时代通过 RHI 抽象层OpenGL 仅为后端之一Qt 6 引入了RHIRendering Hardware Interface渲染硬件接口作为统一的 GPU 抽象层Qt Quick 不再直接调用 OpenGL而是通过 RHI 间接调用底层图形 API支持多后端自动切换平台默认后端可选后端WindowsDirect3D 11Direct3D 12、Vulkan、OpenGLmacOS / iOSMetalVulkan、OpenGLLinuxOpenGLVulkanAndroidOpenGL ESVulkan也就是说Qt6 的 Qt Quick 界面在 Windows 上默认由 D3D11 绘制macOS 上默认由 Metal 绘制只有 Linux 等平台默认继续使用 OpenGL。2.实现原理Qt Painting 模块实现代码在.\Qt5.12.12\5.12.12\Src\qtbase\src\gui\painting下面整体遵循「统一接口 多后端引擎 底层光栅化组件」的分层架构。2.1.整体分层从上到下分为 5 层上层依赖下层下层对上层透明┌───────────────────────────────────────────────────┐ │ 接口层QPainter 绘制数据类Pen/Brush/Path等 │ 用户直接使用 ├───────────────────────────────────────────────────┤ │ 引擎抽象层QPaintEngine / QPaintEngineEx │ 统一绘制接口 ├───────────────────────────────────────────────────┤ │ 引擎实现层QRasterPaintEngine │ 软件光栅化具体实现 ├───────────────────────────────────────────────────┤ │ 光栅化组件层Stroker / OutlineMapper / DrawHelper│ 像素级计算 ├───────────────────────────────────────────────────┤ │ 设备层QPaintDevice 基类 QImage/QPixmap 等 │ 绘制目标载体 └───────────────────────────────────────────────────┘2.2.核心继承关系1.绘制引擎继承链最核心的主干QPaintEngine (抽象基类) ├── QPaintEngineEx (扩展绘制引擎) │ ├── QRasterPaintEngine (光栅绘制引擎 - 主要实现) │ └── QEmulationPaintEngine (模拟绘制引擎 - 包装其他引擎) └── 其他平台特定引擎 [外部类] ├── QOpenGLPaintEngine ├── QWin32PaintEngine └── QX11PaintEngineQPaintEngine公有抽象基类定位所有绘制引擎的根接口定义了全套 2D 绘制虚函数drawRects、drawLines、drawPath、drawText、drawImage等职责管理引擎生命周期、绑定绘制设备、存储基础绘制状态、提供引擎类型标识本目录内的直接子类QPaintEngineEx私有扩展基类_p后缀Qt5 引入的优化版 2D 引擎基类新增批量绘制、状态缓存、统一抗锯齿处理能力对复杂路径、渐变、裁剪做了通用抽象降低具体引擎的实现成本唯一核心子类QRasterPaintEngine私有类纯 CPU 软件光栅化引擎的完整实现是 QtWidgets 的默认渲染后端也是本目录最复杂、最核心的实现类QPicturePaintEngine录制绘制指令到QPicture支持后续回放QPrintEngine打印引擎抽象基类补充OpenGL 绘制引擎、SVG 绘制引擎等不在本目录分属gui/opengl、svg等其他模块。2.绘制设备继承链QPaintDevice (抽象基类) ├── QPagedPaintDevice (分页绘制设备) │ └── QPdfWriter (PDF写入器) ├── QWindow (窗口) [外部类] ├── QImage (图像) [外部类] └── QPixmap (像素图) [外部类]所有可被QPainter绘制的对象都继承自QPaintDevice核心能力是「创建并返回对应类型的绘制引擎」。QPaintDevice公有抽象基类核心虚函数paintEngine()→ 返回该设备对应的绘制引擎实例提供设备度量信息逻辑像素尺寸、物理 DPI、颜色深度等本目录内的子类QImage内存位图设备像素可直接读写纯软件绘制跨平台行为一致QPixmap屏幕适配位图设备平台相关上屏效率更高QBitmap单色位图QPixmap的子类QPicture绘制指令录制设备不生成像素只记录绘制命令QPagedPaintDevice分页设备基类打印场景使用补充QWidgetwidgets 模块、QOpenGLPaintDeviceopengl 模块也是QPaintDevice的子类但不在本目录2.3.核心组合与依赖关系1.QPainter统一入口与调度者QPainter是用户唯一直接使用的绘制入口内部通过组合模式衔接设备与引擎。持有关系持有QPaintDevice*当前绑定的绘制目标持有QPaintEngine*当前使用的绘制引擎由绘制设备创建持有QPainterState状态栈管理画笔、画刷、变换矩阵、裁剪区域、字体、渲染提示等状态支持save()/restore()压栈弹栈工作逻辑 用户所有drawXXX调用先经过QPainter做坐标变换、裁剪校验、状态合并再转发给底层QPaintEngine执行光栅化。2.QRasterPaintEngine软件光栅引擎核心QRasterPaintEngine是本目录的核心实现类内部组合了多个专用组件分工完成从「绘制指令」到「像素缓冲区」的完整转换。QRasterPaintEngine的职责只有一个把QPainter的绘制指令画线、填色、渐变、文字、图片合成等通过 CPU 计算转换成一张像素位图QImage/QPixmap。这一步是纯数学运算不依赖任何操作系统图形 API也不调用 GDI、OpenGL、Metal 等硬件接口因此天然跨平台。这也是 QtWidgets 能做到 “全平台绘制效果完全一致” 的根本原因 —— 所有控件的外观都是 Qt 自己用 CPU 算出来的而非调用系统原生控件渲染。下面是涉及文件和一些内部组件介绍文件核心作用qdrawhelper_p.h/qdrawhelper.cpp底层像素操作核心包含所有 SIMD 加速的光栅化函数矩形填充、线条绘制、渐变、图像混合、抗锯齿采样等qstroker_p.h/qstroker.cpp路径描边算法实现负责将QPainterPath轮廓转换为可光栅化的扫描线qpaintengineex_p.h/qpaintengineex.cpp优化版绘制引擎基类提供通用绘制状态管理、路径裁剪等能力qtextureglyphcache_p.h文字字形缓存将字体字形光栅化后缓存为位图大幅提升文字绘制性能qoutlinemapper_p.h路径轮廓映射器用于复杂路径的抗锯齿光栅化内部组件类型核心职责QRasterBuffer组合持有封装目标像素缓冲区管理像素格式、行步长、脏区域是所有绘制结果的最终写入目标QStroker依赖调用路径描边计算器输入QPainterPathQPen参数输出描边后的闭合轮廓多边形QOutlineMapper依赖调用抗锯齿扫描线生成器输入闭合路径输出带亚像素精度的扫描线覆盖度数据是 Qt 高质量抗锯齿的核心QDrawHelper函数集依赖调用底层像素操作函数集合所有像素填充、alpha 混合、渐变采样、图像缩放的最终执行者带 SIMD 指令集加速QTextureGlyphCache组合持有文字字形缓存缓存已光栅化的字体字形位图避免重复计算大幅提升文字绘制性能不同平台的差异只在 “最后一步显示”光栅化生成像素位图后需要把这张图贴到系统窗口上这一步由 Qt 的平台抽象层QPA负责不同平台的提交方式不同平台光栅化引擎统一最终像素提交到窗口的方式WindowsQRasterPaintEngine通过QBackingStore将位图 Blit 到 Win32 窗口 HDC底层使用 GDIQt 5.15 可配合 DirectComposition 做窗口合成Linux (X11)QRasterPaintEngine通过 XCB 协议将像素缓冲区提交给 X Server 绘制Linux (Wayland)QRasterPaintEngine通过 Wayland 协议共享内存缓冲区提交合成macOSQRasterPaintEngine渲染到CGContextCore Graphics最终上屏到 CALayer嵌入式 Linux (Framebuffer/EGLFS)QRasterPaintEngine直接写入帧缓冲或通过 EGL 表面上屏从 Qt 5 开始Qt 全面重构了绘制管线Qt 4 存在多个平台相关绘制引擎Windows 下有基于 GDI 的QWindowsPaintEngineX11 下有基于 XRender 的引擎macOS 下有基于 QuickDraw/CoreGraphics 的引擎当时软件光栅化引擎只是备选系统原生引擎才是默认导致不同平台下绘制效果、性能差异很大。什么时候不用 QRasterPaintEngine只有主动切换到 GPU 加速渲染路径时才会绕过软件光栅引擎使用QOpenGLWidget、QQuickWidget等 GPU 加速控件全局开启 OpenGL 渲染后端如设置Qt::AA_UseOpenGLES使用 Qt QuickQML界面走 RHI 原生 GPU API 渲染。简单理解上层绘制逻辑全平台共用一套 QRaster 代码保证效果一致底层只封装了 “把像素贴到屏幕” 的平台接口不参与绘制计算。3.底层光栅化组件的协作流程不同绘制图元会走不同的组件组合典型链路简单图元矩形、水平线直接调用QDrawHelper中的 SIMD 函数批量填充像素性能最高路径描边QPainterPath→QStroker生成描边轮廓 →QOutlineMapper生成扫描线 →QDrawHelper逐行填充路径填充QPainterPath→QOutlineMapper直接生成扫描线 →QDrawHelper逐行填充文字绘制字符编码 → 字体引擎生成字形 →QTextureGlyphCache缓存命中 →QDrawHelper拷贝字形位图到目标缓冲区4.绘制数据类值类型这些类是绘制参数的载体都是值语义被QPainter状态栈持有作为参数传递给绘制引擎。QPen描边参数包含线宽、颜色、线型、端点样式、连接样式、虚线模式QBrush填充参数支持纯色、渐变QGradient、纹理贴图三种填充模式QPainterPath路径数据容器支持直线、贝塞尔曲线、圆弧、矩形等图元组合支持路径布尔运算QTransform2D 仿射变换矩阵支持平移、旋转、缩放、错切、透视变换QColor颜色类支持 ARGB、HSV 等多种颜色空间QGradient渐变基类子类包括线性渐变、径向渐变、锥形渐变2.4.Windows 平台 QtWidgets 完整渲染调用链路QtWidgets 在 Windows 上的渲染是典型的「软件光栅化 平台窗口上屏」架构完整流程从触发重绘到像素上屏分为 4 个核心阶段全程默认不依赖 OpenGL。1.重绘触发阶段重绘的源头分两类主动触发代码调用QWidget::update()/repaint()Qt 内部标记脏区域dirty region向事件循环投递一个重绘事件。被动触发窗口移动、缩放、被遮挡后露出、系统发送WM_PAINT消息由 Qt 平台插件QPA接收并转化为重绘请求。关键细节update()是异步合并的多次调用会合并成一次重绘在下一次事件循环时执行避免重复绘制repaint()是同步立即重绘会直接触发 paintEvent常规场景不推荐频繁使用。2.事件分发与脏区计算Windows 消息循环接收到WM_PAINT由QWindowsWindow平台类处理Qt 计算累计的脏区域需要重绘的矩形集合只重绘变化的部分而非全窗口重绘这是性能优化的核心之一调用对应QWidget的paintEvent(QPaintEvent*)虚函数参数中携带脏区矩形。3.光栅化绘制阶段核心这是QRasterPaintEngine真正工作的阶段在paintEvent中创建QPainter(this)Qt 自动为当前控件关联对应的绘制引擎普通 QWidget 默认绑定QRasterPaintEngine绘制目标是QBackingStore管理的一张内存位图QImage格式通常为ARGB32_Premultiplied所有QPainter绘制指令drawLine、drawRect、drawText、drawPath 等都由QRasterPaintEngine拆解为底层像素操作基础图元走qdrawhelper模块的 SIMD 加速函数SSE2/AVX2批量处理像素复杂路径走QStroker描边 扫描线填充算法逐行计算覆盖度实现抗锯齿文字先查字形缓存命中直接拷贝位图未命中则通过 FreeType 光栅化字形后缓存再绘制。所有绘制结果都写入内存中的像素缓冲区全程在 CPU 执行不涉及 GPU。4.缓冲区提交与上屏Windows 特有绘制完成后需要把内存位图的脏区拷贝到屏幕上这一步是 Windows 平台相关的QBackingStore::flush()被调用将 backing store 中脏区的像素提交到窗口表面传统兼容路径通过 Windows GDI 的BitBlt/StretchBlt函数将内存 DIB 位图拷贝到窗口 HDC 上由 DWM桌面窗口管理器最终合成到屏幕优化路径Qt 5.15 / Qt6启用 DirectComposition 支持后Qt 会将 backing store 的内容通过 DirectComposition 表面提交直接交给 DWM 合成减少一次 GDI 拷贝显著提升缩放、动画场景的性能。补充Qt Windows 平台的 backing store 是双缓冲结构绘制在后台缓冲区进行完成后一次性 flush 到前台因此默认不会出现闪烁不需要手动实现双缓冲。2.5.QRaster 软件光栅化 vs OpenGL GPU 渲染 性能对比维度QRaster 软件光栅化OpenGL GPU 渲染计算主体CPU 执行扫描线、像素混合算法GPU 并行执行顶点着色、片元着色数据路径内存生成位图 → 拷贝到窗口顶点 / 纹理上传 GPU → GPU 计算 → 帧缓冲直接上屏并行方式主要依靠 SIMD 指令级并行多线程优化有限天然大规模并行成百上千核心同时计算变换开销缩放、旋转、透视需逐像素重算开销极大矩阵变换由顶点着色器完成几乎零开销两者没有绝对的 “谁更快”优势场景完全不同。以下基于 Windows 桌面平台的常规硬件环境从多个维度做详细对比。1.核心原理差异维度QRaster 软件光栅化OpenGL GPU 渲染计算主体CPU 执行扫描线、像素混合算法GPU 并行执行顶点着色、片元着色数据路径内存生成位图 → 拷贝到窗口顶点 / 纹理上传 GPU → GPU 计算 → 帧缓冲直接上屏并行方式主要依靠 SIMD 指令级并行多线程优化有限天然大规模并行成百上千核心同时计算变换开销缩放、旋转、透视需逐像素重算开销极大矩阵变换由顶点着色器完成几乎零开销2.分场景性能对比(1)常规桌面 UI几十个控件、少量文字与图标QRaster 更快。原因OpenGL 需要创建上下文、切换状态、上传数据有固定的驱动开销而 CPU 光栅化直接内存操作小数据量下延迟更低、响应更快。这也是 QtWidgets 默认不用 OpenGL 的核心原因普通业务界面软件渲染性能完全够用且兼容性更好。(2)大量 2D 图元上千条线、矩形、点如曲线图表、仿真轨迹千级以内两者差距不大QRaster 凭借 SIMD 优化依然够用。万级以上、且每帧动态更新OpenGL 反超并拉开差距。原因CPU 串行处理万个图元会线性增长耗时GPU 并行处理下图元数量增长带来的性能下降平缓很多。(3)频繁缩放、旋转、透明混合如地图、画布类应用OpenGL 压倒性优势。原因仿射变换、透视变换在 GPU 中是硬件级支持只需要修改顶点矩阵即可而软件光栅化下每次变换都要重新计算所有像素的位置、做插值重采样CPU 开销成倍增长。(4)文字密集型界面报表、表格、大量文本QRaster 通常更优。原因文字光栅化本质是字形位图拷贝 灰度抗锯齿CPU 缓存命中率高FreeType Qt 字形缓存已经做了深度优化而 GPU 渲染文字需要先把字形上传纹理小文字频繁切换字形时纹理切换开销反而更高。(5)图片与视频渲染大图缩放、视频帧连续播放OpenGL 优势明显纹理采样、颜色空间转换都可由 GPU 硬件加速。静态小图标展示两者无明显差异。3.其他维度对比内存占用QRaster 需要在内存中保留完整窗口大小的位图高分辨率下内存占用高4K 屏约 32MB 单缓冲OpenGL 帧缓冲在显存中系统内存占用更低。启动与首次绘制开销QRaster 几乎零启动成本OpenGL 需要初始化驱动、创建上下文、编译着色器首帧延迟高。兼容性与稳定性QRaster 纯软件实现几乎不会出现驱动兼容问题OpenGL 受显卡驱动影响大不同厂商、不同版本驱动可能出现渲染异常、崩溃。功耗轻量界面下CPU 渲染功耗更低重度绘制场景下GPU 并行效率更高单位算力功耗更优。开发调试成本QRaster 基于 QPainter 原生 API开发简单调试方便OpenGL 需要学习着色器、管线、资源管理开发与调试门槛高很多。4.选型建议普通业务桌面软件、表单、管理系统默认用 QRaster 软件渲染即可稳定、兼容、开发成本低。大数据量可视化、动态轨迹、实时图表、2D 游戏画布优先考虑 OpenGL 加速。3D 场景、三维仿真必须使用 OpenGL/Vulkan 等 GPU 渲染方案。嵌入式低性能设备若 GPU 算力弱、驱动不完善软件光栅化往往比 GPU 渲染更流畅稳定。3.QOpenGLWidget 中使用 QPainter 进行 GPU 加速 2D 绘制在QOpenGLWidget中直接使用QPainter绘制时Qt 会自动切换到OpenGL 绘制引擎底层为QOpenGLPaintDevice所有 2D 绘制指令都会被转换成 OpenGL 调用由 GPU 完成光栅化完全替代默认的QRasterPaintEngine软件渲染。它最大的优势是:API 零成本迁移和普通 QWidget 中QPainter的用法完全一致现有绘制代码几乎不用改变换性能质变平移、缩放、旋转等操作由 GPU 矩阵硬件运算完成几乎零开销天然抗锯齿GPU 多重采样抗锯齿开销远低于软件抗锯齿画面更流畅项目配置.pro 文件QT core gui widgets opengl CONFIG c17 TARGET OpenGLPainterDemo TEMPLATE app SOURCES main.cpp glpaintwidget.cpp HEADERS glpaintwidget.h头文件glpaintwidget.h:#ifndef GLPAINTWIDGET_H #define GLPAINTWIDGET_H #include QOpenGLWidget #include QOpenGLFunctions #include QMouseEvent #include QWheelEvent #include QPainter class GLPaintWidget : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT public: explicit GLPaintWidget(QWidget *parent nullptr); ~GLPaintWidget() override; protected: // OpenGL 生命周期 void initializeGL() override; void resizeGL(int w, int h) override; void paintGL() override; // 交互事件 void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; void wheelEvent(QWheelEvent *event) override; private: qreal m_zoom 1.0; // 缩放比例 QPoint m_panOffset; // 平移偏移量 QPoint m_lastMousePos; // 上次鼠标位置 bool m_panning false; // 是否处于拖动状态 }; #endif // GLPAINTWIDGET_H源文件glpaintwidget.cpp#include glpaintwidget.h GLPaintWidget::GLPaintWidget(QWidget *parent) : QOpenGLWidget(parent) { // 配置 OpenGL 表面3.3 核心模式 4倍抗锯齿 QSurfaceFormat format; format.setVersion(3, 3); format.setProfile(QSurfaceFormat::CoreProfile); format.setSamples(4); format.setDepthBufferSize(24); setFormat(format); setWindowTitle(QPainter OpenGL GPU 加速绘制); resize(900, 600); } GLPaintWidget::~GLPaintWidget() { // 资源释放QPainter 相关资源由 Qt 内部管理无需手动释放 } void GLPaintWidget::initializeGL() { // 初始化 OpenGL 函数指针必须最先调用 initializeOpenGLFunctions(); // 设置清屏背景色 glClearColor(0.95f, 0.95f, 0.98f, 1.0f); } void GLPaintWidget::resizeGL(int w, int h) { // 视口跟随窗口尺寸 glViewport(0, 0, w, h); } void GLPaintWidget::paintGL() { // 清屏 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 核心QPainter GPU 绘制 // 直接在 QOpenGLWidget 上创建 QPainter自动使用 OpenGL 引擎 QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); painter.setRenderHint(QPainter::TextAntialiasing, true); painter.setRenderHint(QPainter::SmoothPixmapTransform, true); // 应用全局变换平移 缩放GPU 硬件加速零开销 painter.translate(m_panOffset); painter.scale(m_zoom, m_zoom); // 1. 绘制网格背景千级线条GPU 下依然流畅 painter.setPen(QPen(QColor(220, 220, 230), 1)); for (int x -2000; x 2000; x 50) { painter.drawLine(x, -2000, x, 2000); } for (int y -2000; y 2000; y 50) { painter.drawLine(-2000, y, 2000, y); } // 2. 绘制矩形 painter.setPen(QPen(QColor(64, 158, 255), 2)); painter.setBrush(QColor(64, 158, 255, 80)); painter.drawRect(QRect(0, 0, 200, 150)); // 3. 绘制圆形 painter.setPen(QPen(QColor(255, 103, 103), 2)); painter.setBrush(QColor(255, 103, 103, 80)); painter.drawEllipse(QPoint(320, 100), 80, 80); // 4. 渐变填充圆角矩形 QLinearGradient gradient(0, 200, 200, 350); gradient.setColorAt(0, QColor(0, 200, 150)); gradient.setColorAt(1, QColor(0, 150, 200)); painter.setBrush(gradient); painter.setPen(Qt::NoPen); painter.drawRoundedRect(0, 200, 200, 150, 12, 12); // 5. 贝塞尔曲线路径 QPainterPath path; path.moveTo(260, 250); path.cubicTo(360, 200, 360, 360, 460, 310); painter.setPen(QPen(QColor(155, 89, 182), 3)); painter.setBrush(Qt::NoBrush); painter.drawPath(path); // 6. 文字绘制 painter.setPen(QColor(40, 40, 40)); painter.setFont(QFont(Microsoft YaHei, 16, QFont::Bold)); painter.drawText(20, 420, GPU加速2D绘制 | 左键拖动平移 | 滚轮缩放); // 7. 大量随机点性能测试10000 个点依然流畅 painter.setPen(QPen(QColor(255, 193, 7), 2)); for (int i 0; i 10000; i) { int x qrand() % 800 50; int y qrand() % 400 50; painter.drawPoint(x, y); } // } // ------------------------------ 交互逻辑 ------------------------------ void GLPaintWidget::mousePressEvent(QMouseEvent *event) { if (event-button() Qt::LeftButton) { m_panning true; m_lastMousePos event-pos(); } } void GLPaintWidget::mouseMoveEvent(QMouseEvent *event) { if (m_panning) { m_panOffset event-pos() - m_lastMousePos; m_lastMousePos event-pos(); update(); // 触发重绘 } } void GLPaintWidget::wheelEvent(QWheelEvent *event) { // 滚轮缩放每步缩放 10% qreal factor event-angleDelta().y() 0 ? 1.1 : 0.9; m_zoom * factor; update(); }主函数main.cpp#include QApplication #include glpaintwidget.h int main(int argc, char *argv[]) { QApplication a(argc, argv); GLPaintWidget w; w.show(); return a.exec(); }4.Qt RHI 渲染架构RHIRendering Hardware Interface渲染硬件接口是 Qt 6 最核心的底层重构彻底改变了 Qt 的 GPU 渲染体系也是理解现代 Qt 渲染机制的关键。4.1.诞生背景Qt 5 时代Qt Quick 2 的场景图直接基于 OpenGL ES 2.0 开发所有渲染指令硬编码调用 OpenGL API。随着图形行业发展这套架构出现了致命短板苹果在 macOS/iOS 全面弃用 OpenGL主推 MetalOpenGL 驱动停止更新性能与兼容性持续退化Windows 平台 Direct3D 驱动更稳定、功耗更低是游戏与工业软件的主流选择Vulkan 作为新一代跨平台图形 API在 Linux、Android 快速普及不同厂商的 OpenGL 驱动差异巨大适配与调试成本极高因此 Qt 6 从零构建了 RHI 抽象层上层只调用统一的 RHI API底层自动适配各平台原生图形 API设计理念与 Unity、Unreal 等游戏引擎的渲染抽象层一致。4.2.分层架构RHI 是纯 GPU 渲染抽象层不负责窗口、事件、输入只专注于 GPU 资源管理与绘制指令提交。整体架构分层如下┌─────────────────────────────────────┐ │ Qt Quick / Qt 3D / 自定义渲染代码 │ 上层业务 ├─────────────────────────────────────┤ │ Qt Scene Graph场景图 │ 场景裁剪、批处理 ├─────────────────────────────────────┤ │ Qt RHI API │ 统一抽象层 ★ ├──────┬──────┬───────┬───────────────┤ │D3D11 │D3D12 │ Metal │ Vulkan / GL │ 平台图形后端 └──────┴──────┴───────┴───────────────┘核心价值一次编写多后端运行同一份渲染代码无需修改即可在不同图形 API 上执行自动最优适配根据操作系统自动选择原生图形 API发挥最佳性能与兼容性屏蔽底层差异统一的资源、管线、着色器模型开发者无需学习多套图形 API4.3.支持的图形后端Qt 6 目前支持 6 种图形后端不同平台默认值不同运行平台默认后端可选后端说明WindowsDirect3D 11Direct3D 12、Vulkan、OpenGLD3D11 兼容性最广D3D12 性能更强macOS / iOSMetalVulkan、OpenGLMetal 为苹果官方推荐功耗与性能最优Linux (X11/Wayland)OpenGLVulkan开源驱动生态下 Vulkan 性能更优AndroidOpenGL ES 3.0Vulkan中高端设备支持 Vulkan嵌入式 LinuxOpenGL ESVulkan依硬件驱动支持而定可通过环境变量QSG_RHI_BACKEND手动强制指定后端用于调试或特殊场景# Windows 强制使用 Vulkan set QSG_RHI_BACKENDvulkan # macOS 强制使用 OpenGL export QSG_RHI_BACKENDopengl4.4.核心渲染流程与关键类RHI 采用基于命令缓冲区的延迟渲染模型与现代图形 APID3D12、Vulkan、Metal设计理念对齐。核心流程分为三个阶段初始化创建 RHI 实例、交换链、全局资源资源准备创建缓冲区、纹理、图形管线、资源绑定帧渲染录制绘制命令 → 提交到 GPU → 呈现到屏幕核心类与作用QRhiRHI 核心实例代表一个 GPU 逻辑设备是所有 GPU 资源的工厂QRhiSwapChain交换链对应窗口的可显示表面管理双缓冲 / 三缓冲与垂直同步QRhiBufferGPU 缓冲区存储顶点、索引、Uniform 常量等数据QRhiTextureGPU 纹理资源支持 2D、立方图、数组纹理等QRhiGraphicsPipeline图形管线封装着色器、深度测试、混合模式、光栅化等所有固定管线状态QRhiShaderResourceBindings着色器资源绑定关联 Uniform 缓冲区、纹理采样器与着色器输入槽QRhiCommandBuffer命令缓冲区录制所有绘制、资源拷贝、状态切换指令最后批量提交给 GPU4.5.RHI 在 Qt 各模块中的应用Qt QuickQMLQt 6 中场景图已完全基于 RHI 重写是 RHI 最大的使用方。所有 QML 界面元素最终都会被转换成 RHI 绘制指令由底层 GPU API 执行。Qt 3DQt 3D 渲染后端已迁移至 RHI支持多图形 API 切换。Qt Multimedia视频解码后的帧渲染通过 RHI 实现 GPU 加速输出。Qt Widgets传统 Widgets 默认仍使用 CPU 软件光栅化可通过两种方式接入 RHI使用QQuickWidget嵌入 QML 界面间接使用 RHI 渲染Qt 6.4 提供QRhiWidget控件可直接在 Widget 窗口中使用 RHI API 自定义绘制是替代QOpenGLWidget的新一代方案4.6.选型建议开发传统 QtWidgets 桌面应用仅需嵌入 3D 场景或高性能 2D 绘制QOpenGLWidget仍是最成熟、资料最多、上手最快的方案。开发新一代跨平台应用基于 Qt Quick / QML 架构默认基于 RHI无需关心底层自动享受最优性能与平台适配。追求极致性能、面向未来图形 API或针对特定平台深度优化可基于QRhiWidget开发自定义渲染逻辑逐步替代 OpenGL。