QQuickRenderControl Class
QQuickRenderControl 类提供了一种机制,可将Qt Quick 场景图以完全由应用程序控制的方式渲染到离屏渲染目标上。更多内容...
| 头文件: | #include <QQuickRenderControl> |
| CMake: | find_package(Qt6 REQUIRED COMPONENTS Quick) target_link_libraries(mytarget PRIVATE Qt6::Quick) |
| qmake: | QT += quick |
| 继承自: | QObject |
公共函数
| QQuickRenderControl(QObject *parent = nullptr) | |
| virtual | ~QQuickRenderControl() override |
(since 6.0) void | beginFrame() |
(since 6.6) QRhiCommandBuffer * | commandBuffer() const |
(since 6.0) void | endFrame() |
(since 6.0) bool | initialize() |
| void | invalidate() |
| void | polishItems() |
| void | prepareThread(QThread *targetThread) |
| void | render() |
| virtual QWindow * | renderWindow(QPoint *offset) |
(since 6.6) QRhi * | rhi() const |
(since 6.0) int | samples() const |
(since 6.0) void | setSamples(int sampleCount) |
| bool | sync() |
(since 6.0) QQuickWindow * | window() const |
信号
| void | renderRequested() |
| void | sceneChanged() |
静态公共成员
| QWindow * | renderWindowFor(QQuickWindow *win, QPoint *offset = nullptr) |
详细说明
QQuickWindow 以及QQuickView 及其相关的内部渲染循环,将Qt Quick 场景渲染到本机窗口上。在某些情况下,例如与第三方OpenGL、Vulkan、Metal或Direct 3D渲染器集成时,将场景导入纹理以便外部渲染引擎以任意方式使用会非常有用。 在与 VR 框架集成时,此类机制同样至关重要。QQuickRenderControl 能够以硬件加速的方式实现这一点,而使用QQuickWindow::grabWindow() 的替代方案在性能上则存在局限。
使用 QQuickRenderControl 时,QQuickWindow 不能是shown (否则它将不会在屏幕上显示),且不会为其创建底层原生窗口。取而代之的是,通过调用QQuickWindow 构造函数的重载版本,并将通过QQuickWindow::setRenderTarget() 指定的纹理或图像对象与渲染控件对象关联,从而将QQuickWindow 实例与渲染控件对象关联起来。QQuickWindow 对象仍然必不可少,因为它代表Qt Quick 场景,并提供了大部分场景管理和事件传递机制。然而,从窗口系统的角度来看,它并不作为真正的屏幕窗口存在。
图形设备、上下文、图像和纹理对象的管理由应用程序负责。Qt Quick 将使用的设备或上下文必须在调用initialize()之前创建。纹理对象的创建可以推迟,详见下文。 Qt 5.4 引入了QOpenGLContext 采用现有原生上下文的功能。结合 QQuickRenderControl,这使得可以创建一个与外部渲染引擎现有上下文共享的QOpenGLContext 。随后,该新的QOpenGLContext 可用于将Qt Quick 场景渲染到纹理中,该纹理也可被其他引擎的上下文访问。 对于 Vulkan、Metal 和 Direct 3D,Qt 并未提供设备对象的封装类,因此可以将现有对象通过 `QQuickWindow::setGraphicsDevice()` 原样传递。
QML组件的加载和实例化是通过QQmlEngine 实现的。根对象创建后,需要将其作为子对象添加到QQuickWindow 的contentItem()中。
应用程序通常需要连接以下 4 个重要信号:
- QQuickWindow::sceneGraphInitialized() 在调用QQuickRenderControl::initialize() 之后某个时刻触发。接收到此信号后,应用程序应创建其帧缓冲区对象,并将其与QQuickWindow 关联。
- QQuickWindow::sceneGraphInvalidated() 当场景图资源被释放时,帧缓冲区对象也可被销毁。
- QQuickRenderControl::renderRequested() 表示必须通过调用 `render()` 来渲染场景。在将上下文设为当前上下文后,应用程序应调用 `render()`。
- QQuickRenderControl::sceneChanged() 表示场景已发生变化,这意味着在渲染之前,还需要进行润色和同步。
要向场景发送事件(例如鼠标或键盘事件),请使用QCoreApplication::sendEvent(),并将QQuickWindow 实例作为接收者。
对于键事件,可能还需要手动将焦点设置在所需的项目上。实际上,这涉及在所需项目(例如场景的根项目)与场景(QQuickWindow )关联后,调用该项目的forceActiveFocus() 方法。
成员函数文档
[explicit] QQuickRenderControl::QQuickRenderControl(QObject *parent = nullptr)
创建一个 QQuickRenderControl 对象,其父对象为parent 。
[override virtual noexcept] QQuickRenderControl::~QQuickRenderControl()
销毁该实例。释放所有场景图资源。
另请参阅 invalidate()。
[since 6.0] void QQuickRenderControl::beginFrame()
指定图形帧的开始。对sync()或render()的调用必须被beginFrame()和endFrame()的调用所包围。
与早期仅支持 OpenGL 的 Qt 5 不同,使用其他图形 API 进行渲染需要更明确地定义帧的起始和结束点。当通过 `QQuickRenderControl` 手动驱动渲染循环时,现在需要由 `QQuickRenderControl ` 的用户来指定这些点。
一个典型的更新步骤(包括将渲染结果初始化到现有纹理中)可能如下所示。该示例代码片段基于 Direct3D 11,但相同的概念也适用于其他图形 API。
if(!m_quickInitialized) {
m_quickWindow->setGraphicsDevice(QQuickGraphicsDevice::fromDeviceAndContext(m_engine->device(), m_engine->context()));
if(!m_renderControl->initialize())
qWarning("Failed to initialize redirected Qt Quick rendering");
m_quickWindow->setRenderTarget(QQuickRenderTarget::fromNativeTexture({ quint64(m_res.texture), 0},
QSize(QML_WIDTH,QML_HEIGHT),
SAMPLE_COUNT));
m_quickInitialized= true;
}
m_renderControl->polishItems();
m_renderControl->beginFrame();
m_renderControl->sync();
m_renderControl->render();
m_renderControl->endFrame();//Qt Quick 的渲染命令在此处提交至设备上下文注意: 当使用software 对Qt Quick 的适配版本时,此函数 既无需调用,也不得调用。
注意:在内部, beginFrame() 和endFrame() 分别调用beginOffscreenFrame() 和endOffscreenFrame()。这意味着在调用此函数时,QRhi 上不得有任何帧(无论是离屏帧还是基于交换链的帧)正在被录制。
该函数于 Qt 6.0 中引入。
另请参阅 endFrame()、initialize()、sync()、render()、QQuickGraphicsDevice 以及QQuickRenderTarget 。
[since 6.6] QRhiCommandBuffer *QQuickRenderControl::commandBuffer() const
返回当前的命令缓冲区。
一旦调用beginFrame(),系统会自动建立一个QRhiCommandBuffer 。这是场景图Qt Quick 所使用的命令缓冲区,但在某些情况下,应用程序可能也需要查询该缓冲区,例如为了执行资源更新(例如纹理回读)。
返回的命令缓冲区引用仅应在beginFrame()与endFrame()之间使用。存在特定例外情况,例如在endFrame()之后、但下一个beginFrame()之前,对该命令缓冲区调用lastCompletedGpuTime()是有效的。
注意: 当使用software 适配的Qt Quick 时,此 函数不适用且返回 null。
该函数在 Qt 6.6 中引入。
另请参阅 rhi()、beginFrame() 和endFrame()。
[since 6.0] void QQuickRenderControl::endFrame()
指定图形帧的结束。对sync()或render()的调用必须被beginFrame()和endFrame()的调用所包围。
调用此函数时,场景图中排入队列的任何图形命令将被提交至上下文或命令队列(视具体情况而定)。
注意: 当使用Qt Quick 的software 变体时,无需且不得调用此 函数。
该函数在 Qt 6.0 中引入。
另请参阅 beginFrame()、initialize()、sync()、render()、QQuickGraphicsDevice 以及QQuickRenderTarget 。
[since 6.0] bool QQuickRenderControl::initialize()
初始化场景图资源。当使用 Vulkan、Metal、OpenGL 或 Direct3D 等图形 API 进行Qt Quick 渲染时,调用此函数后,QQuickRenderControl 将设置相应的渲染引擎。只要QQuickRenderControl 存在,该渲染基础设施就一直存在。
若要控制Qt Quick 使用哪种图形 API,请使用QSGRendererInterface:GraphicsApi 常量之一调用QQuickWindow::setGraphicsApi()。此操作必须在调用本函数之前完成。
若要防止场景图创建自己的设备和上下文对象,请通过调用QQuickWindow::setGraphicsDevice() 指定一个适当的QQuickGraphicsDevice ,该对象应封装现有的图形对象。
若要配置要启用的设备扩展(例如,针对 Vulkan),请在本函数调用之前调用QQuickWindow::setGraphicsConfiguration()。
注意:在 使用 Vulkan时, QQuickRenderControl 不会自动创建QVulkanInstance 。相反,应用程序有责任使用QQuickWindow 创建合适的QVulkanInstance 和associate it 。在初始化QVulkanInstance 之前,强烈建议通过调用静态函数QQuickGraphicsConfiguration::preferredInstanceExtensions() 查询Qt Quick 所需的实例扩展列表,并将返回的列表传递给QVulkanInstance::setExtensions()。
成功时返回true ,否则返回false 。
注意: 在使用Qt Quick 的software 适配体时,无需且不得调用此 函数。
使用默认的Qt Quick 适配时,此函数会创建一个新的QRhi 对象,这与未使用QQuickRenderControl 时屏幕上的QQuickWindow 的行为类似。要使这个新的QRhi 对象采用某些现有的设备或上下文资源(例如,使用现有的QOpenGLContext 而不是创建一个新的),请如上所述使用QQuickWindow::setGraphicsDevice()。 当应用程序希望让Qt Quick 的渲染使用已存在的QRhi 对象时,也可通过QQuickGraphicsDevice::fromRhi()实现。当设置了此类QQuickGraphicsDevice (其引用了已存在的QRhi )时,initialize()中将不会创建新的、专用的QRhi 对象。
该函数在 Qt 6.0 中引入。
另请参阅 QQuickRenderTarget 、QQuickGraphicsDevice 以及QQuickGraphicsConfiguration::preferredInstanceExtensions()。
void QQuickRenderControl::invalidate()
停止渲染并释放资源。
这相当于当窗口被隐藏时,真实的QQuickWindow 所执行的清理操作。
该函数由析构函数调用。因此通常无需直接调用它。
一旦调用了 invalidate(),就可以通过再次调用initialize() 来重用该QQuickRenderControl 实例。
注意:此 函数不会考虑 QQuickWindow::persistentSceneGraph() 或 QQuickWindow::persistentGraphics()。这意味着与上下文相关的资源将始终被释放。
void QQuickRenderControl::polishItems()
应尽可能在调用 `sync()` 之前尽早调用此函数。在多线程环境下,渲染操作可以与该函数并行进行。
void QQuickRenderControl::prepareThread(QThread *targetThread)
准备在GUI线程之外渲染Qt Quick 场景。
targetThread 指定将在此线程上进行同步和渲染。在单线程场景下,无需调用此函数。
void QQuickRenderControl::render()
使用当前上下文渲染场景图。
[signal] void QQuickRenderControl::renderRequested()
当需要渲染场景图时,会发出此信号。无需调用sync()。
注意: 当此信号被发出时,请避免 直接触发渲染。建议通过使用定时器等方式延迟渲染。这样可以获得更好的性能。
[virtual] QWindow *QQuickRenderControl::renderWindow(QPoint *offset)
在子类中重新实现,以返回该渲染控件实际进行渲染的目标窗口。
如果 `offset ` 不为空,则将其设置为该控件在窗口内的偏移量。
注意:虽然 并非强制要求,但重写此函数对于支持具有不同设备像素比的多屏幕环境,以及正确定位从 QML 打开的弹出窗口至关重要。因此,强烈建议在子类中提供此函数。
[static] QWindow *QQuickRenderControl::renderWindowFor(QQuickWindow *win, QPoint *offset = nullptr)
返回win 正在渲染到的实际窗口(如果存在)。
如果 `offset ` 不为空,则将其设置为该窗口内渲染内容的偏移量。
[since 6.6] QRhi *QQuickRenderControl::rhi() const
返回与该QQuickRenderControl 关联的QRhi 。
注意: QRhi 仅在initialize() 成功执行后才 存在。在此之前,返回值为 null。
注意: 当使用 `Qt Quick` 的 `software ` 适配器时,此 函数不适用且返回 `null`。
该函数在 Qt 6.6 中引入。
另请参阅 commandBuffer()、beginFrame() 和endFrame()。
[since 6.0] int QQuickRenderControl::samples() const
返回当前的采样数。1 或 0 表示不进行多采样。
该函数在 Qt 6.0 中引入。
另请参阅 setSamples()。
[signal] void QQuickRenderControl::sceneChanged()
当场景图更新时会发出此信号,这意味着需要调用polishItems() 和sync()。如果sync() 返回 true,则需要调用render()。
注意: 当此信号被触发时,请避免 直接执行润色、同步和渲染操作。建议通过使用定时器等方式推迟这些操作。这样可以获得更好的性能。
[since 6.0] void QQuickRenderControl::setSamples(int sampleCount)
设置多采样所使用的采样数。当sampleCount 为0或1时,多采样功能将被禁用。
注意:此 函数必须与多采样渲染目标配合使用,这意味着sampleCount 必须与传递给QQuickRenderTarget::fromNativeTexture()的采样数一致,而该采样数又必须与原生纹理的采样数一致。
该函数在 Qt 6.0 中引入。
另请参阅 samples()、initialize() 和QQuickRenderTarget 。
bool QQuickRenderControl::sync()
此函数用于将 QML 场景与渲染场景图进行同步。
如果使用了专用的渲染线程,则在调用此函数期间应阻塞 GUI 线程。
如果同步操作更改了场景图,则返回true。
[since 6.0] QQuickWindow *QQuickRenderControl::window() const
返回与该QQuickRenderControl 关联的QQuickWindow 。
注意: 在构造QQuickWindow 时,QQuickRenderControl 才会 与QQuickWindow 建立关联。在此之前,该函数的返回值为 null。
该函数于 Qt 6.0 中引入。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.