PySide6.QtQuick.QQuickRenderControl¶
- class QQuickRenderControl¶
QQuickRenderControl类提供了一种机制,用于以完全由应用程序控制的方式将 Qt Quick 场景图渲染到离屏渲染目标上。更多…概要¶
方法¶
def
__init__()def
beginFrame()def
commandBuffer()def
endFrame()def
initialize()def
invalidate()def
polishItems()def
prepareThread()def
render()def
rhi()def
samples()def
setSamples()def
sync()def
window()
虚拟方法¶
def
renderWindow()
信号¶
def
sceneChanged()
静态函数¶
注意
本文档可能包含从C++自动翻译到Python的代码片段。我们始终欢迎对代码片段翻译的贡献。如果您发现翻译问题,您也可以通过在我们的https:/bugreports.qt.io/projects/PYSIDE上创建工单来告知我们。
详细描述¶
QQuickWindow和QQuickView及其相关的内部渲染循环将 Qt Quick 场景渲染到原生窗口上。在某些情况下,例如与第三方 OpenGL、Vulkan、Metal 或 Direct 3D 渲染器集成时,将场景获取到纹理中,然后由外部渲染引擎以任意方式使用,可能会很有用。在与 VR 框架集成时,这种机制也是必不可少的。QQuickRenderControl以硬件加速的方式实现了这一点,与性能受限的替代方案grabWindow()不同。当使用
QQuickRenderControl时,QQuickWindow不能被显示(它不会在屏幕上可见),并且不会有底层的原生窗口。相反,QQuickWindow实例与渲染控制对象相关联,使用QQuickWindow构造函数的重载,并通过setRenderTarget()指定的纹理或图像对象。QQuickWindow对象仍然是必不可少的,因为它代表了Qt Quick场景,并提供了大部分的场景管理和事件传递机制。然而,从窗口系统的角度来看,它并不充当真正的屏幕窗口。图形设备、上下文、图像和纹理对象的管理由应用程序负责。Qt Quick 使用的设备或上下文必须在调用
initialize()之前创建。纹理对象的创建可以推迟,详见下文。Qt 5.4 引入了 QOpenGLContext 采用现有本地上下文的能力。与QQuickRenderControl结合使用,可以创建一个与外部渲染引擎现有上下文共享的 QOpenGLContext。然后,这个新的 QOpenGLContext 可以用于将 Qt Quick 场景渲染到纹理中,该纹理也可以被其他引擎的上下文访问。对于 Vulkan、Metal 和 Direct 3D,Qt 没有提供设备对象的封装,因此现有的对象可以通过setGraphicsDevice()直接传递。QML组件的加载和实例化是通过使用QQmlEngine来完成的。一旦创建了根对象,它需要被设置为
QQuickWindow的contentItem()的子对象。应用程序通常需要连接到4个重要信号:
sceneGraphInitialized()在调用initialize()之后的某个时刻发出。在此信号发出时,应用程序应创建其帧缓冲对象并将其与QQuickWindow关联。sceneGraphInvalidated()当场景图资源被释放时,帧缓冲对象也可以被销毁。renderRequested()表示需要通过调用render()来渲染场景。在使上下文成为当前上下文后,应用程序应调用render()。sceneChanged()表示场景已更改,这意味着在渲染之前,还需要进行抛光和同步。
要向场景发送事件,例如鼠标或键盘事件,请使用QCoreApplication::sendEvent(),并将
QQuickWindow实例作为接收者。对于关键事件,可能还需要手动将焦点设置在所需的项目上。实际上,这涉及到在所需的项目上调用
forceActiveFocus(),例如场景的根项目,一旦它与场景(QQuickWindow)关联。注意
一般来说,
QQuickRenderControl支持与所有 Qt Quick 后端结合使用。然而,某些功能,特别是 grab(),可能并非在所有情况下都可用。构造一个
QQuickRenderControl对象,父对象为parent。- 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's rendering commands are submitted to the device context here注意
在使用Qt Quick的
software适配时,不需要也不得调用此函数。注意
在内部,beginFrame() 和
endFrame()分别调用 beginOffscreenFrame() 和 endOffscreenFrame()。这意味着在调用此函数时,QRhi 上不得有正在记录的帧(无论是离屏帧还是基于交换链的帧)。- commandBuffer()¶
- Return type:
QRhiCommandBuffer
返回当前命令缓冲区。
一旦调用了
beginFrame(),就会自动设置一个QRhiCommandBuffer。这是Qt Quick场景图使用的命令缓冲区,但在某些情况下,应用程序可能还希望查询它,例如发出资源更新(例如,纹理回读)。返回的命令缓冲区引用应仅在
beginFrame()和endFrame()之间使用。有特定的例外情况,例如在endFrame()之后但在下一个beginFrame()之前调用命令缓冲区上的lastCompletedGpuTime()是有效的。- endFrame()¶
指定图形帧的结束。对
sync()或render()的调用必须包含在对beginFrame()和endFrame()的调用中。当调用此函数时,由场景图排队的任何图形命令将提交到上下文或命令队列,视情况而定。
注意
在使用Qt Quick的
software适配时,不需要也不得调用此函数。- initialize()¶
- Return type:
布尔
初始化场景图资源。当使用图形API(如Vulkan、Metal、OpenGL或Direct3D)进行Qt Quick渲染时,
QQuickRenderControl将在调用此函数时设置适当的渲染引擎。只要QQuickRenderControl存在,此渲染基础设施就会存在。要控制Qt Quick使用的图形API,请使用
setGraphicsApi()并传入QSGRendererInterface中的GraphicsApi常量之一。这必须在调用此函数之前完成。为了防止场景图创建自己的设备和上下文对象,通过调用
setGraphicsDevice(),指定一个适当的QQuickGraphicsDevice,包装现有的图形对象。要配置启用哪些设备扩展(例如,对于Vulkan),请在此函数之前调用
setGraphicsConfiguration()。注意
在使用Vulkan时,
QQuickRenderControl不会自动创建QVulkanInstance。相反,应用程序有责任创建一个合适的QVulkanInstance并将其与QQuickWindow关联。在初始化QVulkanInstance之前,强烈建议通过调用静态函数preferredInstanceExtensions()查询Qt Quick所需的实例扩展列表,并将返回的列表传递给QVulkanInstance::setExtensions()。成功时返回
true,否则返回false。注意
在使用Qt Quick的
software适配时,不需要也不得调用此函数。使用默认的Qt Quick适配时,此函数会创建一个新的QRhi对象,类似于在没有使用
QQuickRenderControl时,屏幕上的QQuickWindow会发生的情况。为了使这个新的QRhi对象采用一些现有的设备或上下文资源(例如使用现有的QOpenGLContext而不是创建一个新的),请使用上面提到的setGraphicsDevice()。当应用程序希望使Qt Quick渲染使用已经存在的QRhi对象时,也可以通过fromRhi()实现。当设置了这样一个引用已经存在的QRhi的QQuickGraphicsDevice时,initialize()中将不会创建新的、专用的QRhi对象。- invalidate()¶
停止渲染并释放资源。
这相当于当窗口隐藏时,真实的
QQuickWindow所执行的清理操作。此函数从析构函数中调用。因此通常不需要直接调用它。
一旦调用了invalidate(),就可以通过再次调用
initialize()来重用QQuickRenderControl实例。注意
此函数不考虑 QQuickWindow::persistentSceneGraph() 或 QQuickWindow::persistentGraphics()。这意味着特定于上下文的资源总是会被释放。
- polishItems()¶
此函数应尽可能在
sync()之前调用。在多线程场景中,渲染可以与此函数并行进行。准备在GUI线程之外渲染Qt Quick场景。
targetThread指定了同步和渲染将发生的线程。在单线程场景中不需要调用此函数。- render()¶
使用当前上下文渲染场景图。
- renderRequested()¶
当场景图需要渲染时,会发出此信号。不需要调用
sync()。注意
当此信号发出时,避免直接触发渲染。相反,建议通过使用计时器等方式来延迟渲染。这将带来更好的性能。
在子类中重新实现,以返回此渲染控件正在渲染的实际窗口。
如果
offset不为空,它将被设置为控件在窗口内的偏移量。注意
虽然不是强制性的,但为了实现支持具有不同设备像素比的多屏幕以及正确定位从QML打开的弹出窗口,重新实现此函数变得至关重要。因此,强烈建议在子类中提供它。
- static renderWindowFor(win[, offset=None])¶
- Parameters:
win –
QQuickWindowoffset –
QPoint
- Return type:
返回
win正在渲染到的实际窗口(如果有的话)。如果
offset不为空,它将被设置为其窗口内渲染的偏移量。- rhi()¶
- Return type:
QRhi
返回与此
QQuickRenderControl关联的QRhi。注意
QRhi 仅在
initialize()成功完成后存在。在此之前,返回值为 null。- samples()¶
- Return type:
整数
返回当前的样本计数。1 或 0 表示没有多重采样。
另请参阅
- sceneChanged()¶
当场景图更新时,会发出此信号,这意味着需要调用
polishItems()和sync()。如果sync()返回true,则需要调用render()。注意
当此信号发出时,避免直接触发抛光、同步和渲染。相反,建议使用计时器等方式将其推迟。这将带来更好的性能。
- setSamples(sampleCount)¶
- Parameters:
sampleCount – int
设置用于多重采样的样本数量。当
sampleCount为0或1时,多重采样被禁用。注意
此函数始终与多重采样渲染目标结合使用,这意味着
sampleCount必须与传递给QQuickRenderTarget::fromNativeTexture()的采样计数匹配,而后者又必须与本机纹理的采样计数匹配。- sync()¶
- Return type:
布尔
此函数用于将QML场景与渲染场景图同步。
如果使用了专用的渲染线程,GUI线程在此调用期间应被阻塞。
如果同步改变了场景图,则返回true。
- window()¶
- Return type:
返回与此
QQuickRenderControl关联的QQuickWindow。注意
当构造
QQuickWindow时,QQuickRenderControl会与QQuickWindow关联。在此之前,此函数的返回值为空。