我有一个QML GridView
,其中包含大量简单的图标。这个数字可以是数百万,但同时只能看到大约一千个,并且只有几十种类型的图像,所以我猜它们应该被很好地缓存。
如果我使用PNG
图像,一切都很好。启动时间相对较长,但在渲染完所有内容后,应用程序即使在低规格机器上也能正常运行,并且GridView
中的滚动/调整大小/缩放也快速而平滑。
但是,如果我使用SVG
代替,它会大大减慢我的系统速度。即使在渲染完所有内容之后,应用程序的响应性也很糟糕,即使与GridView无关的GUI元素也显示出明显的延迟,鼠标光标几乎无法移动等等。我认为渲染后,SVG会像其他任何一样呈现图片。如果我甚至不与他们互动,为什么CPU必须忙?而且,最重要的是,我能做些什么吗?如果我的SVG图像只包含一个矩形,并且在每个单元格中使用相同的图像,则会发生同样的情况。所以它必须意味着对象本身正在做某事。
答案 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 ...”的文字......