PySide6.QtQuick.QQuickRenderControl

class QQuickRenderControl

QQuickRenderControl 类提供了一种机制,用于以完全由应用程序控制的方式将 Qt Quick 场景图渲染到离屏渲染目标上。更多

PySide6.QtQuick.QQuickRenderControl 的继承图

概要

方法

虚拟方法

信号

静态函数

注意

本文档可能包含从C++自动翻译到Python的代码片段。我们始终欢迎对代码片段翻译的贡献。如果您发现翻译问题,您也可以通过在我们的https:/bugreports.qt.io/projects/PYSIDE上创建工单来告知我们。

详细描述

QQuickWindowQQuickView 及其相关的内部渲染循环将 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个重要信号:

要向场景发送事件,例如鼠标或键盘事件,请使用QCoreApplication::sendEvent(),并将QQuickWindow实例作为接收者。

对于关键事件,可能还需要手动将焦点设置在所需的项目上。实际上,这涉及到在所需的项目上调用forceActiveFocus(),例如场景的根项目,一旦它与场景(QQuickWindow)关联。

注意

一般来说,QQuickRenderControl 支持与所有 Qt Quick 后端结合使用。然而,某些功能,特别是 grab(),可能并非在所有情况下都可用。

__init__([parent=None])
Parameters:

父对象QObject

构造一个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()是有效的。

注意

此函数不适用,在使用Qt Quick的software适配时返回null。

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()之前调用。在多线程场景中,渲染可以与此函数并行进行。

prepareThread(targetThread)
Parameters:

targetThreadQThread

准备在GUI线程之外渲染Qt Quick场景。

targetThread 指定了同步和渲染将发生的线程。在单线程场景中不需要调用此函数。

render()

使用当前上下文渲染场景图。

renderRequested()

当场景图需要渲染时,会发出此信号。不需要调用sync()

注意

当此信号发出时,避免直接触发渲染。相反,建议通过使用计时器等方式来延迟渲染。这将带来更好的性能。

renderWindow(offset)
Parameters:

偏移量QPoint

Return type:

QWindow

在子类中重新实现,以返回此渲染控件正在渲染的实际窗口。

如果 offset 不为空,它将被设置为控件在窗口内的偏移量。

注意

虽然不是强制性的,但为了实现支持具有不同设备像素比的多屏幕以及正确定位从QML打开的弹出窗口,重新实现此函数变得至关重要。因此,强烈建议在子类中提供它。

static renderWindowFor(win[, offset=None])
Parameters:
Return type:

QWindow

返回win正在渲染到的实际窗口(如果有的话)。

如果 offset 不为空,它将被设置为其窗口内渲染的偏移量。

rhi()
Return type:

QRhi

返回与此QQuickRenderControl关联的QRhi。

注意

QRhi 仅在 initialize() 成功完成后存在。在此之前,返回值为 null。

注意

此函数不适用,在使用Qt Quick的software适配时返回null。

samples()
Return type:

整数

返回当前的样本计数。1 或 0 表示没有多重采样。

另请参阅

setSamples()

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:

QQuickWindow

返回与此QQuickRenderControl关联的QQuickWindow

注意

当构造QQuickWindow时,QQuickRenderControl会与QQuickWindow关联。在此之前,此函数的返回值为空。