QML 项目可见性和计算

QML Item visibility and computation

我有一个 qml 文件 BackgrounPage.qml,它用作我应用程序中所有 qml 页面的背景。

此背景可以是渐变色、纯色或图像。

所以我做了:

BackgroundPage{

  property bool isGradient: false
  property bool isSolid: true //by default
  property bool isImage: false

  //gradient background
  Rectangle{
    visible: isGradient

    ...//create the rectangle

    LinearGradient{
      ...//create gradient
    }
  }

  //solid background
  Rectangle{
    visible: isSolid

    //create rectangle

    color: ...
  }

  Image{
    visible: isImage
    source: ...
  }
}

它工作得很好,但为了性能、优化,我想知道一个不可见的项目是否是由 QML 计算的。如果我创建纯色背景,我不想计算渐变和图像。

所以我的问题是:不可见项是在 QML 中计算的吗?

对你来说 "computed" 是什么?

是的,对象已创建并且 "alive" - 因此如果有任何绑定影响这些项目,将评估这些对象。

是否会渲染? 不。当它们不可见时,引擎会阻止它们进入 GPU。

要验证该声明,请参阅此示例:

ApplicationWindow {
    id: window
    visible: true
    width: 600
    height: 600


    Rectangle {
        width: 100
        height: 100
        color: 'green'

        Timer {
            running: true
            interval: 1000
            repeat: true
            onTriggered: parent.visible = !parent.visible
        }
    }
}

Rectangle 的可见性每秒切换一次。
如果您观察通过设置环境变量生成的输出:

QSG_DEBUG_RENDERER=render

您会看到,这会在 0 和 1 之间切换渲染节点的数量。

Rendering:
 -> Opaque: 0 nodes in 0 batches...
 -> Alpha: 0 nodes in 0 batches...
 -> times: build: 0, prepare(opaque/alpha): 0/0, sorting: 0, upload(opaque/alpha): 0/0, render: 0
Renderer::render() QSGAbstractRenderer(0x2341b258) "rebuild: full"
Rendering:
 -> Opaque: 1 nodes in 1 batches...
 -> Alpha: 0 nodes in 0 batches...
 - 0x38589200 [  upload] [noclip] [opaque] [  merged]  Nodes:    1  Vertices:     4  Indices:     6  root: 0x0
 -> times: build: 0, prepare(opaque/alpha): 0/0, sorting: 0, upload(opaque/alpha): 0/0, render: 1
Renderer::render() QSGAbstractRenderer(0x2341b258) "rebuild: none"

然而,更好的解决方案是使用 Loader 加载正确的组件:

Loader {
    sourceComponent: (isGradient ? gradientComponent :
                      (isSolid ? solidComponent :
                       (isImage ? imageComponent : null)))
    Component {
        id: gradientComponent
        ...
    }
    ...
}