为什么动态qml对象的创建如此缓慢,有哪些合理的替代方案?

时间:2016-08-30 10:41:02

标签: performance qt qml

我想要实现的类似于棋盘游戏。有一个100 * 100网格,放在Item内,位于Flickable

"游戏板的各个矩形"是svg图像,目前大约有20种类型,这可能会增加到数百种。

作为基准测试,我只是尝试填充"世界"元素:

Component.onCompleted:
{
    var i,j;
    for (i=0; i<100; ++i) 
        for (j=0; j<100; ++j)
        {
            var type = (i+j) % 20;

            Qt.createQmlObject('import QtQuick 2.0; Image {source:"qrc:///icons/img/symbol'+type+'.svg";
                width: 32*scaling.factor;
                height: 32*scaling.factor;
                x:'+i*32+'*scaling.factor;
                y:'+j*32+'*scaling.factor}',
                mainScreen);
        }
}

在中等优质的PC上超过5秒

但是,在加载完所有内容后,它会平稳运行,滚动和缩放(scaling.factor是由滑块或旋转框设置的浮动)。

svg图像非常简单,只包含几个基本形状。如果我尝试加载一个简单的矩形而不是svg图像

Qt.createQmlObject('import QtQuick 2.0; Rectangle {color
     : "red"; width: 32; height: 32; x:'+i*32+'; y:'+j*32+'}',
     mainScreen);

它仍然需要大约3秒钟。即使没有图像,也没有动态缩放。

我记得20年前,在单核,低于400 MHz CPU的计算机上运行策略游戏,这些游戏有更大的地图,更复杂的瓷砖,动画,寻路等等。我们不是甚至谈论3d。

现代PC如何能够显示几千个非常基本的形状?它不应该是来自磁盘的加载时间,因为元素在资源文件中,甚至使用矩形而不是图像的测试也非常慢。

不保持所有这些显示,只加载可见屏幕边框附近的元素显然是一种方法,或者如果我有10000 * 10000的地图。我希望能够同时显示100 * 100个项目,特别是在具有良好分辨率的屏幕上,大部分都是可见的。

我是否遗漏了一些明显的东西,或者我是否应该完全忘记Qt Quick?我应该在OpenGL或某些2D引擎中手动完成所有操作吗?

修改

根据评论的建议,Qt.createQmlObject非常慢。

因此我尝试了

var component = Qt.createComponent("field.qml");
component.createObject(mainScreen, {"x": i*32, "y": j*32 });

field.qml只包含一个Rectangle{},或者在第二个测试中,只有空Item{}。在这两种情况下,10000次迭代花费超过3秒。将svg添加到field.qml只会使时间增加0.8秒。

那么,是不是应该缓存的图像?即使我有相同的简单svg(只包含3个简单的矩形)重复遍历,它需要大量的时间。

使用Repeater{}可以让一切变得更快。空Rectangle s渲染大约0.2到0.3秒,svg图像在一秒钟内渲染。 (然而,这种方法有其他缺点。当我完成不同方法的测试后,我会发布答案)

1 个答案:

答案 0 :(得分:2)

(虽然它没有完全解决我的具体问题,但我会将此作为答案发布,因为它符合问题的范围,可能对其他人有用。)

虽然官方示例使用动态创建对象,但该方法仅在对象数量相当低时才有用。对于非常多的项目,flyway.baselineOnMigrate = true ListView的优点是只渲染实际位于视图边界内的项目。

TableView

TableView { anchors.fill: parent model: ListModel {} itemDelegate: MyField{} Component.onCompleted: { var i; for (i=0; i<10000; ++i) { model.append({}); } } Qt.createQmlObject快几个数量级,比Component.createObject

更容易处理