剔除在可见区域外的物品。

4
文档中可以看到:

默认的渲染器不会在CPU端进行视口裁剪或遮挡检测。如果某些物体不应该被显示,它们就不应该被展示。对于不需要绘制的项目,请使用Item::visible: false。不添加这样的逻辑的主要原因是它会增加额外的成本,这也会损害那些已经注意行为良好的应用程序。

那么有没有什么技巧可以轻松做到,而不必自己实现呢?

请注意,在我的情况下,处于可见区域之外的项目存在于ScrollView中,并且没有滚动到。

我想执行裁剪是为了减少全场景重新绘制所需的CPU使用率。


你是在使用软件渲染器吗?因为Qt Quick总是在GPU上渲染整个场景,对其影响不大。 - Kuba hasn't forgotten Monica
2
列表视图会自动完成这个任务,并且只加载接近可见区域的项目,但是你需要将模型作为数据后端。如果没有这个,就需要一个自定义的数据结构来存储被剔除的内容,还需要进行相当多的坐标映射,而且它有一个缺点——无法反映发生在“离线”项目上的更改。 - dtech
最后,如果不知道实际使用场景,就几乎不可能提供一种实现策略。 “滚动视图中的项目”可以是很多东西,范围从非常到无法优化... - dtech
只需计算物品相对于视图的“绝对位置”,如果它在视图跟踪的可见区域内,则启用,否则禁用。然而,我并不认为仅将可见性设置为false会带来很大的收益。跟踪和切换可见性可能会消耗更多的CPU。 - dtech
@StefanMonov - 这是个好消息,但你的 CPU 使用率如此之高有些奇怪。我的项目轻松处理 20k 个对象,通过绑定在一个复杂的树形结构中布局。你的目标硬件是什么样的?或者可能是这些项的问题? - dtech
显示剩余8条评论
2个回答

5

这里是一个可以扩展的简单示例:

Window {
  visible: true
  width: 640
  height: 480

  Rectangle {
    anchors.centerIn: parent
    width: 200
    height: 200
    color: "yellow"

    Flickable {
      id: view
      anchors.fill: parent
      contentWidth: 200
      contentHeight: col.height
      property real span : contentY + height
      Column {
        id: col
        x: 90
        spacing: 2
        Repeater {
          model: 50
          delegate: Rectangle {
            width: 10
            height: 10
            color: inView ? "blue" : "red"
            property bool inView: y > view.contentY && y < view.span
          }
        }
      }
    }
  }
}

显然,一个完美的解决方案还应该包括物品的高度在计算中。如果必要,您也可以在x轴上进行检查。


我会说应该是 y >= view.contentY && y + height <= view.span 或者 y + height >= view.contenY && y <= view.span ;-) - Amfasis

0
补充dtech的回答,我刚学到有QML组件,例如GridView和ListView,可以自动进行剔除。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接