Qt Quick 的变化
Qt 6 是经过深思熟虑的努力,使框架更高效、更易用。
我们尽量保持每个发布版中所有公共 API 的二进制和源代码兼容性。但是,为了使 Qt 成为更好的框架,一些变化是不可避免的。
在本主题中,我们总结了 Qt Quick 的这些变化,并提供了解决这些变化的指导。
Qt Quick QML 类型中的变化
font.weight 类型已更改
font.weight
的类型已更改为 int
。预定义的权重类仍然存在,但现在可以使用任意整数来选择不匹配这些权重类的字体。这确保了它与 C++ API 的一致性,在 C++ API 中,始终可以使用任意整数表达字体权重。
大多数代码不会受到影响,除非使用了从字符串到枚举值的隐式转换。
font.weight: "Bold"
以下代码将无法正确解析,必须替换为其等效的枚举值,如下所示。
font.weight: Font.Bold
FontLoader.name 现为只读属性
在 Qt 5 中,FontLoader 的 name
属性是可写的,并且在设置时会覆盖项的源属性。这导致对其目的的某些混淆,并且在冲突属性的设置器之间存在竞态条件时可能会导致不确定的行为。
这意味着以下代码将不再工作。
FontLoader { id: fontLoader name: "Helvetica" } Text { font.family: fontLoader.name text: "Foobar" }
相反,请使用自定义属性来存储字体家族名称。
property string fontName: "Helvetica" Text { font.family: fontName text: "Foobar" }
OpenGLInfo QML 类型已删除
在 Qt 5.8 中,OpenGLInfo 已废弃,并且已被删除以用于 Qt 6。请使用 GraphicsInfo 代替。
ShaderEffect 不再支持内联 GLSL 着色器字符串
与 自定义材料 一样,效果不再以 GLSL 着色器字符串的形式指定。相反,着色器预计要由 Qt Shader Tools 模块中的工具(如 qsb
命令行工具)预处理,从而确保无论在运行时使用哪种图形 API(Vulkan、Metal、OpenGL 或 Direct 3D)都可以使用着色器资产。预期 ShaderEffect 项引用生成的 .qsb
文件。
ShaderEffect 源属性现在是 URL
The ShaderEffect属性vertexShader和fragmentShader现在都具有QUrl的类型,而不是QByteArray。因此,它们的行为与其他类似属性(如Image.source)相同。通过file
或qrc
方案引用文件的现有代码将继续按原样工作。此外,此更改还允许通过相对于组件(.qml文件)位置的路径引用文件。因此,现在指定file:
方案是可选的。
Qt Quick C++ API的更改
QQuickItem的更改
QQuickItem的几何更改()函数已重命名为geometryChange。
QQuickWidget的更改
QQuickWidget只在场景图以OpenGL渲染时才可用。在使用其他图形API(如Vulkan或Metal)时,它将不可用。依赖QQuickWidget的应用程序应在它们的main()函数中调用QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL)
,以强制使用OpenGL。
QQuick* API的更改
- 希望集成自己的Vulkan、Metal或Direct3D渲染命令集的应用程序应知道,除了QQuickWindow::beforeRendering()和afterRendering()之外,还有新的QQuickWindow信号。现有的Qt 5模式仅在下述信号连接之前(或之后)通常不再足够,并且可能还需要通过连接到其他信号来补充,例如beforeRenderPassRecording或afterRenderPassRecording。
- 依赖QQuickWindow::beforeRendering或afterRendering()信号来发布自己的一组OpenGL渲染命令的应用程序应在OpenGL调用之前调用QQuickWindow::beginExternalCommands(),并在OpenGL调用之后调用QQuickWindow::endExternal Commands。这确保了应用程序代码所做的状态更改不会与场景图渲染器自己的缓存状态混淆。请注意,正如在Qt 5中一样,更改Qt Quick渲染器未使用的OpenGL 3.x或4.x状态仍然可能导致意外问题,因此建议在从连接到这些信号的插槽或lambda返回之前,将任何此类OpenGL状态重置为默认值。
- 已删除现有的QQuickWindow::setRenderTarget()重载及其相关获取器,并将它们替换为接收一个QQuickRenderTarget的新函数。现在,执行与QQuickRenderControl结合的重新定向渲染的应用程序现在应使用此新函数来指定未绑定到OpenGL的渲染目标。
- 接收一个QSGRendererInterface::GraphicsApi参数的QQuickWindow::setSceneGraphBackend()重载已被重命名为setGraphicsApi。
- QQuickWindow的函数setPersistentOpenGLContext和isPersistentOpenGLContext已被重命名,现在分别是QQuickWindow::setPersistentGraphics()和QQuickWindow::isPersistentGraphics。
setClearBeforeRendering
()和clearBeforeRendering
()已从QQuickWindow
中删除。在Qt 6中,没有跳过颜色缓存清除的选项。在Qt 5与底层结合使用时,调用setClearBeforeRendering
()通常是必要的,以防止Qt Quick清除渲染到颜色缓存中的内容。在Qt 6中,有更健壮的方法:连接到在清除之后、渲染Qt Quick内容之前的beforeRenderPassRecording
信号。QQuickWindow::openglContext
函数已被删除。当应用程序确保场景图使用OpenGL进行渲染时,可以通过QSGRendererInterface::getResource
从QOpenGLContext
获取。QQuickWindow::openglContextCreated
信号已被删除。- 已废弃的
QQuickWindow::createTextureFromId
函数已被删除。代替使用,使用来自QPlatformInterface::QSGOpenGLTexture
、QPlatformInterface::QSGVulkanTexture
、QPlatformInterface::QSGD3D11Texture
或QPlatformInterface::QSGMetalTexture
的fromNative()函数。 QQuickFramebufferObject
类提供了一个不变的API,但只有在使用OpenGL渲染场景图时才能正常工作。在使用Vulkan或Metal等其他图形API时,它将无法工作。依赖于QQuickFramebufferObject
的应用程序应该在main()函数中调用QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGL)
以强制使用OpenGL。QQuickRenderControl
的API略有变动:现在已删除grab()函数,在有适用性的情况下使用QQuickWindow::grabWindow
()代替。initialize()函数不再接受一个QOpenGLContext
。现在,应用程序还需要根据需要调用QQuickRenderControl::beginFrame
()和QQuickRenderControl::endFrame
。当需要抗锯齿时,必须调用新的函数QQuickRenderControl::setSamples
以指示样本计数。- 希望与现有的本地图形设备或上下文对象一起进行Qt Quick渲染的应用程序必须使用新的
QQuickWindow::setGraphicsDevice
()函数,因为QQuickRenderControl
不再提供initialize(QOpenGLContext*)
函数。 - 将
QQuickPaintedItem
和Context2D
设置为Framebuffer
模式没有效果。它将表现得像是设置了默认的Image模式。 QSG_NO_DEPTH_BUFFER
环境变量在Qt 6.0中仍然受到支持,但其使用建议被替换为在关联到QQuickWindow
的QQuickGraphicsConfiguration
上调用setDepthBufferFor2D
()。
到QSG* API的改变
- QSGMaterialShader 的接口已更改。实现不应再依赖于OpenGL,并且不能假设函数如已移除的 updateState() 会与一个当前的 QOpenGLContext 关联调用。在新的面向数据的接口中,updateState() 被替换为 updateUniformData()、updateSampledImage() 和 updateGraphicsPipelineState()。现在,不再提供作为字符串的GLSL着色器代码,着色器现在应通过Qt Shader Tools模块中的工具预处理器处理,如
qsb
命令行工具,从而确保着色器资源无论在运行时使用哪种图形API(Vulkan、Metal、OpenGL或Direct 3D)都可以使用。 - 已移除 QSGEngine。如果应用程序使用此类,建议改为使用 QQuickRenderControl。
- QSGAbstractRenderer 现在不再是公开的。此类与 QSGEngine 结合使用才有意义,且该类已被移除,QSGAbstractRenderer 已被移回私用。
- 已移除 QSGSimpleMaterial 便利类。应用程序应使用修订的、不依赖于OpenGL的 QSGMaterial API。
- 要访问 QSGTexture 的底层本地纹理对象,不再提供 textureId()。相反,使用 QSGTexture::platformInterface() 与 QPlatformInterface::QSGOpenGLTexture、QPlatformInterface::QSGVulkanTexture、QPlatformInterface::QSGD3D11Texture 或 QPlatformInterface::QSGMetalTexture。
- QSGImageNode 的子类现在需要重写新的附加虚拟函数,如 setAnisotropyLevel() 和 anisotropyLevel()。
- QSGTexture 的子类可能需要重新设计。一些特定的OpenGL虚拟函数,如 bind() 或 updateBindOptions(),已不再存在,而有一些新的虚拟函数是必须实现的,如 comparisonKey()。
Qt Quick中OpenGL使用的变化
尽管对于许多应用程序来说这似乎不会造成中断,但应用开发者应知道,OpenGL不再总是Qt 6中Qt Quick渲染的默认选择。除非使用 software
后端,否则Qt Quick应用程序可在运行时使用OpenGL、Vulkan、Metal或Direct3D 11。如果没有明确的请求,无论是通过 QSG_RHI_BACKEND
环境变量还是通过 QQuickWindow::setSceneGraphBackend() 函数,Qt Quick都会选择平台特定的默认值。
获取更多信息,请访问 Qt Quick Scene Graph 和 Qt Quick Scene Graph Default Renderer 页面。
© 2024 Qt公司有限。本文件中包含的文档贡献为各自所有者的版权。本文件中提供的文档获免费软件基金会发布的 GNU自由文档许可版本1.3 许可。Qt和相关标志是芬兰和/或其他国家和地区Qt公司的商标。所有其他商标均属其各自所有者的财产。