Reputation: 923
I'm creating a "dotted paper" component for my QML app. Essentially this components consists of a dotted background that the user can zoom upon. To create this I used the following code:
DottedPaper.qml
import QtQuick 2.15
Rectangle{
id: page
property int spacing: 50
// this property changes the spacing between the dots
property real contentScale: 1.0
Repeater{
id: rowRepeater
model: 200
Repeater{
id: row
property int rowIndex: index
model: 200
Rectangle{
id: circle
color: "red"
width: 4; height: 4
x: index * spacing * page.contentScale + width/2;
y: rowIndex * spacing * page.contentScale+ height/2
radius: width/2
}
}
}
}
Then in my main file I have the following:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
Flickable{
clip: true // doesn't improve anything
anchors.fill: parent
contentWidth: paper.width
contentHeight: paper.height
DottedPaper{
id: paper
width: 10000; height: 10000;
clip: true
}
}
// the slider changes the content scale of the dotted paper
Slider{
from: 1
to: 3
onValueChanged: paper.contentScale = value
}
}
The problem with this code is that it's slow. Upon checking the application does not render the content at 60fps, but I get around 45 - 50 fps on my desktop. I suspect the issues is that QML is reevaluating the contentScale property binding for each circle in the background even if the circle is not visible on the screen. What is the best way to prevent this?
Upvotes: 0
Views: 962
Reputation: 8277
It works a lot better if you change your Repeaters to be ListViews. That's because a ListView is smart enough to only create enough delegates as needed for the visible space. (At first I thought a GridView would work, but that doesn't give you enough control over rows/columns.)
Rectangle{
id: page
property int cellWidth: 50 * contentScale
property int dotWidth: 4
// this property changes the spacing between the dots
property real contentScale: 1.0
ListView {
id: grid
model: 200
anchors.fill: parent
anchors.leftMargin: page.dotWidth / 2
anchors.topMargin: page.dotWidth / 2
spacing: page.cellWidth - page.dotWidth
delegate: ListView {
model: 200
width: window.width
height: page.dotWidth
orientation: ListView.Horizontal
spacing: page.cellWidth - page.dotWidth
property int rowIndex: index
delegate: Rectangle{
id: circle
color: "red"
width: page.dotWidth; height: page.dotWidth
radius: width/2
}
}
}
}
Upvotes: 3