从模型动态填充大地图

Posted

技术标签:

【中文标题】从模型动态填充大地图【英文标题】:Dynamically populating a large map from a model 【发布时间】:2017-03-27 20:57:37 【问题描述】:

我正在尝试在 Flickable 中放置大量(5k - 10k 个元素)的矩形。数据来自自定义模型,QAbstractListModel 的子类。预期结果如下所示:

我的第一种方法是使用带有委托的中继器来创建这样的矩形:

Repeater 
    id: repeater
    model: particleListModel
    delegate: mapDelegate


Component 
    id: mapDelegate

Rectangle 
    property bool checked: false
    id: particle
    color: "transparent"
    width: model.boundswidth
    height: model.boundsheight
    x: model.boundsx
    y: model.boundsy
    MouseArea 
        id: mouseArea
        anchors.fill: parent
        hoverEnabled: true
        onClicked: 
            console.log(model.index)
            particleIndex = model.index
        
    
    border.color: mouseArea.containsMouse ? "lightgreen" : (model.index === particleIndex) ? "green" : "red"
    border.width: 1.5
    

这可以很好地显示矩形,但是加载需要很长时间(大约 6 秒)并且在加载时会阻塞 UI。 因此,我的第二个方法是使用 Loader 异步填充地图,如下所示:

Component 
    id: mapDelegate

    Loader 
        id: particle
        asynchronous: true
        onLoaded: 
            console.log("loaded " + model.index)
        

        sourceComponent:
            Rectangle 
                property bool checked: false
                color: "red"
                width: model.boundswidth
                height: model.boundsheight
                x: model.boundsx
                y: model.boundsy
                MouseArea 
                    id: mouseArea
                    anchors.fill: parent
                    hoverEnabled: true
                    onClicked: 
                        console.log(model.index)
                        particleIndex = model.index
                    
                
                border.color: mouseArea.containsMouse ? "lightgreen" : (model.index === particleIndex) ? "green" : "red"
                border.width: 1.5
            
        
    

虽然这有效且不会阻塞 UI,但完成所有元素的加载需要很长时间(约 25 秒)。前几个元素加载得非常快,但到最后加载变得越来越缓慢,速度减慢到可以看到单个元素被添加的程度。

我想提高在不阻塞 UI 的情况下在合理时间内加载所有元素的性能。还有另一种我想念的方式吗?或者有没有一种优雅的方式来只加载当前视图中需要的元素?在这里采取什么正确的方法?

【问题讨论】:

【参考方案1】:

如果您要处理大量数据,则可以利用的技术很少。

    先在后台加载数据,比如使用 webworker,然后 将处理后的输出传递给视图。避免操纵视图本身。 尝试仅加载当前可见的块或元素。

这里的想法是快速加载初始屏幕,然后在后台进行其余处理并向其中添加元素。如果您尝试一次放置所有 10k 个元素,则不会产生理想的结果。

在第一次加载时优先考虑您的数据和视图,然后再进行操作。

【讨论】:

以上是关于从模型动态填充大地图的主要内容,如果未能解决你的问题,请参考以下文章

模型中的 Laravel 动态可填充

Django:如何使用动态(非模型)数据预填充 FormView?

包含静态预填充和动态用户数据的核心数据

如何从两个模型填充 ModelChoiceField

使用从一个模型填充到另一个模型来检索数组数据

从站点地图和数据库填充 ASP.NET 菜单