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

Posted

技术标签:

【中文标题】我可以阻止静止的 SVG 图像在 QML 中使用过多的 CPU 资源吗?【英文标题】:Can I stop stationary SVG images from using excesssive CPU resources in QML? 【发布时间】:2016-11-25 12:50:54 【问题描述】:

我有一个 QML GridView,里面有大量简单的图标。数量可以上百万,但同时可见的只有一千左右,而且只有几十种类型的图像,所以我想它们应该被缓存好。

如果我使用PNG 图像,一切都很好。启动时间比较长,但是渲染完一切后,即使在低配机器上应用也能正常运行,GridView中的滚动/调整大小/缩放也快速流畅。

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

【问题讨论】:

【参考方案1】:

“数量可能以百万计” 和 *“启动时间相对较长”——这些陈述值得讨论您的数据模型和位图缓存策略的设计。但是您没有提供任何代码。所以以下是猜测。

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

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

无论如何,请尝试确保您的 sourceSize.width 和 sourceSize.height 与您的渲染宽度/高度匹配。

        Image 
            id: icon
            anchors.centerIn: parent
            source: "cloud.svg"
            sourceSize.width: 50
            sourceSize.height: 50
            width: 50
            height: 50
        

【讨论】:

【参考方案2】:

加载 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...”的文字...

【讨论】:

问题是即使在它们被加载之后,即使我根本不滚动网格,GUI 仍然明显滞后。 那么,我认为你使用的是javascriptor C++阻塞函数... 如何获得图标的列表模型?如果您在所有应用程序中都出现延迟,我敢肯定您的某些功能会花费太多时间

以上是关于我可以阻止静止的 SVG 图像在 QML 中使用过多的 CPU 资源吗?的主要内容,如果未能解决你的问题,请参考以下文章

光栅化 Alpha8 格式的 QML SVG 图像

QML中的SVG未在Android上显示

SVG 阻止触摸/鼠标滚轮事件

如何在 QML 中处理大量的瓦片?

如何在cpp文件中阻止qml中的按钮?

使用 QML 绘制 SVG