我可以阻止静态SVG图像在QML中使用过多的CPU资源吗?

时间:2016-11-25 12:50:54

标签: performance qml

我有一个QML GridView,其中包含大量简单的图标。这个数字可以是数百万,但同时只能看到大约一千个,并且只有几十种类型的图像,所以我猜它们应该被很好地缓存。

如果我使用PNG图像,一切都很好。启动时间相对较长,但在渲染完所有内容后,应用程序即使在低规格机器上也能正常运行,并且GridView中的滚动/调整大小/缩放也快速而平滑。

但是,如果我使用SVG代替,它会大大减慢我的系统速度。即使在渲染完所有内容之后,应用程序的响应性也很糟糕,即使与GridView无关的GUI元素也显示出明显的延迟,鼠标光标几乎无法移动等等。我认为渲染后,SVG会像其他任何一样呈现图片。如果我甚至不与他们互动,为什么CPU必须忙?而且,最重要的是,我能做些什么吗?如果我的SVG图像只包含一个矩形,并且在每个单元格中使用相同的图像,则会发生同样的情况。所以它必须意味着对象本身正在做某事。

2 个答案:

答案 0 :(得分:1)

"数字可以是数百万" 和*"启动时间相对较长" - 这些声明需要讨论您的设计数据模型和位图缓存策略。但是你没有提供任何代码。所以以下是猜测。

我不确定您是用C ++代码还是通过QML加载SVG图像,但我怀疑您在导入SVG时没有设置sourceSize(宽度和高度)属性。因此,它会以大得多的大小映射到内存中,而不是渲染到的内存。也就是说,与使用预先设置的PNG文件相比,它占用的内存要多得多。或者它可能以较小的尺寸进行映射,而Qt则需要花费大量时间在运行时调整这些图像的大小,因为它会滚动进出视图。

使用记事本打开一个SVG文件,查看属性以查看导入大小。

在任何情况下,请尝试确保sourceSize.width和sourceSize.height与渲染宽度/高度相匹配。

 (loop for x downfrom 999 to 998 do (loop for y downfrom 999 to 998 collect (* x y)))

答案 1 :(得分:0)

加载SVG是一项昂贵的操作...... Gridview管理动态对象..每次创建可见项目并销毁不可见项目......因此,每次移动网格时都必须渲染SVG

一个非常糟糕的主意是使用:

    GridVIew{
      cacheBuffer : 6000 
      //create 6000 items ...long startup time and memory expensive
    ...
      }

这是一个更好的选择:

    Image {
        id: icon
        asynchronous : true //load image in asyncronus thread
        sourceSize.width: width //scale as item size
        sourceSize.height: height //scale as item size
         ...
        }

如果负载太慢,您可以在项目背景中添加类似“LOADING ...”的文字......