I am trying to position a largish number (5k - 10k elements) of rectangles in a Flickable. The data comes from a custom model, a subclass of QAbstractListModel. The expected outcome looks like this:
My first approach was to use a Repeater with a delegate to create the rectangles like this:
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
}
}
This works fine to display the rectangles, however it takes a good while to load (~6 seconds) and blocks the UI while it does so. Therefore my seconds approach was to use a Loader to populate the map asynchronously like so:
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
}
}
}
While this works and does not block the UI it takes a long time to finish loading all the elements (~25 seconds). The first few elements load very quickly but the loading gets more and more sluggish towards the end, slowing down to a point where you can watch single elements being added.
I would like to increase the performance to load all elements within a reasonable time while not blocking the UI. Is there another way I am missing? Or is there an elegant way to only load the elements needed in the current view? What would be the right approach to take here?