class QQuickRenderControl#

QQuickRenderControl 类提供了一个机制,可以在完全由应用程序控制的方式下将 Qt Quick 场景图渲染到离屏渲染目标。更多信息...

Inheritance diagram of PySide6.QtQuick.QQuickRenderControl

概述#

方法#

虚拟方法#

信号#

静态函数#

备注

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

详细描述#

QQuickWindowQQuickView 以及它们的关联内部渲染循环在原生窗口上渲染 Qt Quick 场景。在某些情况下,例如与第三方 OpenGL、Vulkan、Metal 或 Direct 3D 渲染器集成时,将场景放入可由外部渲染引擎任意使用的纹理中非常有用。这种机制在集成 VR 框架时也是必不可少的。与其他导致性能下降的替代方案(如使用 grabWindow())不同,QQuickRenderControl 以硬件加速的方式实现了这一功能。

在使用 QQuickRenderControl 时,QQuickWindow 必须不可见(它不会在屏幕上可见),并且将没有底层的原生窗口。相反,QQuickWindow 实例与渲染控制对象关联,使用 QQuickWindow 构造函数的重载,以及通过 setRenderTarget() 指定的纹理或图像对象关联。尽管 QQuickWindow 对象仍然是必需的,因为它代表着 Qt Quick 场景,并提供了大量场景管理和事件传递机制,但它并不会作为窗口系统视角下的实际屏幕窗口。

图形设备、上下文、图像和纹理对象的管理由应用程序负责。在调用 initialize() 之前,必须创建将使用 Qt Quick 的设备或上下文。纹理对象的创建可以延迟,请参阅下文。Qt 5.4 引入了 QOpenGLContext 采取现有本地上下文的能力。与 QQuickRenderControl 结合,这使得可以创建一个与外部渲染引擎现有上下文共享的 QOpenGLContext。此新的 QOpenGLContext 可以用于将 Qt Quick 场景渲染到其他引擎的上下文可访问的纹理中。对于 Vulkan、Metal 和 Direct 3D,没有为设备对象提供 Qt 提供的包装器,因此现有的可以原样通过 setGraphicsDevice() 传递。

通过 QQmlEngine 实现加载和实例化 QML 组件。一旦创建了根对象,它需要将其关联到 QQuickWindow 的 contentItem()。

应用程序通常需要连接到 4 个重要的信号

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

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

备注

一般来说,《QQuickRenderControl》与所有Qt Quick后端兼容。然而,某些功能,尤其是在某些情况下,可能无法使用grab()

__init__([parent=None])#
参数:

parent - QObject

构建一个具有父对象parentQQuickRenderControl对象。

beginFrame()#

指定图形帧的开始。在对sync()render()的调用中必须包含对beginFrame()endFrame()的调用。

与Qt 5早期仅支持OpenGL的世界不同,使用其他图形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上不能有任何帧(无论是离屏帧还是基于swapchain的帧)正在记录。

commandBuffer()#
返回类型:

QRhiCommandBuffer

返回当前命令缓冲区。

调用 beginFrame() 后,将自动设置 QRhiCommandBuffer。这是 Qt Quick 场景图使用的命令缓冲区,但在某些情况下,应用程序可能还需要查询它,例如进行资源更新(例如,纹理读取回)。

返回的命令缓冲区引用仅在 beginFrame()endFrame() 之间使用。存在一些特定异常,例如在 endFrame() 之后和下次 beginFrame() 之前调用 lastCompletedGpuTime() 是有效的。

备注

当使用 Qt Quick 软件适配时,此函数不适用并返回 null。

endFrame()#

指定图形框架的结束。调用 sync()render() 必须在 beginFrame() 和 endFrame() 之间进行。

当调用此函数时,由场景图排队的所有图形命令将被提交到上下文或命令队列,具体取决于应用场景。

备注

在使用Qt Quick的software版本时,不需要也不应该调用此函数。

initialize()#
返回类型:

bool

初始化场景图资源。当使用例如 Vulkan、Metal、OpenGL 或 Direct3D 等图形 API 渲染 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 时,init() 函数中将不会创建新的 QRhi 对象。

invalidate()#

停止渲染并释放资源。

这相当于当窗口变为隐藏时,真实的 QQuickWindow 执行的清理操作。

这个函数是从析构函数中调用的。因此通常不需要直接调用它。

一旦调用了 invalidate(),就可以通过再次调用 initialize() 来重用 QQuickRenderControl 实例。

备注

此函数不考虑QQuickWindow::persistentSceneGraph()或QQuickWindow::persistentGraphics()。这意味着上下文特定的资源总是会被释放。

polishItems()#

此函数应该在调用sync()之前尽可能晚地调用。在多线程场景中,渲染可以与此函数并行进行。

prepareThread(targetThread)#
参数:

targetThreadQThread

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

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

render()#

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

renderRequested()#

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

备注

避免在发出此信号时直接触发渲染。例如,最好通过使用计时器等延迟它。这样可以提高性能。

renderWindow(offset)#
参数:

offsetQPoint

返回类型:

QWindow

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

如果offset非空,它将设置为控制在此窗口内的偏移。

备注

虽然不是强制性的,但在支持不同设备像素比的多屏幕以及正确定位从QML打开的弹出窗口时,重写此函数变得至关重要。因此,在子类中提供它是非常推荐的。

静态 renderWindowFor(win[, offset=None])#
参数:
返回类型:

QWindow

如果有的话,返回win被渲染到的实际窗口。

如果offset非空,它将设置为在该窗口内的渲染偏移。

rhi()#
返回类型:

QRhi

返回与此QQuickRenderControl关联的QRhi。

备注

initialize() 函数成功完成后,QRhi 才存在。在此之前,返回值是 null。

备注

当使用 Qt Quick 软件适配时,此函数不适用并返回 null。

samples()#
返回类型:

int

返回当前采样数量。1 或 0 表示无多采样。

参阅

setSamples()

sceneChanged()#

当场景图更新时,会发出此信号,意味着需要调用 polishItems()sync()。如果 sync() 返回 true,则需要调用 render()

备注

在发出此信号时,避免直接触发抛光、同步和渲染。相反,最好使用定时器等来延迟处理。这将提高性能。

setSamples(sampleCount)#
参数:

sampleCount – int

设置用于多采样的样本数。当 sampleCount 为 0 或 1 时,禁用多采样。

备注

此函数通常与多采样渲染目标一起使用,这意味着 sampleCount 必须与传递给 QQuickRenderTarget::fromNativeTexture() 的样本数匹配,而 QQuickRenderTarget::fromNativeTexture() 的样本数必须与原生纹理的样本数匹配。

sync()#
返回类型:

bool

此函数用于同步 QML 场景与渲染场景图。

如果使用专用渲染线程,则在调用此函数期间应阻塞 GUI 线程。

如果同步改变了场景图,则返回 true

window()#
返回类型:

QQuickWindow

返回与此 QQuickWindow 相关的 QQuickRenderControl

备注

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