I have the following qml application:
import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.0
import QtQuick.Window 2.0
ApplicationWindow {
id: window
width: 480
height: 240
RowLayout {
Rectangle {
width: window.height
height: window.height
radius: window.height / 2
color: "black"
}
Canvas {
id: canvas
width: window.height
height: window.height
onPaint: {
var ctx = canvas.getContext('2d');
var originX = window.height / 2
var originY = window.height / 2
var radius = window.height / 2
ctx.save();
ctx.beginPath();
ctx.arc(originX, originY, radius, 0, 2 * Math.PI);
ctx.fillStyle = Qt.rgba(0, 0, 0, 1);
ctx.fill();
ctx.restore();
}
}
}
}
This produces two black circles next to each other. The left one (the Rectangle
) is crisp on a Retina display, while the right one (the Canvas
) is quite blurry. If I add
antialiasing: false
to the Canvas
, it produces coarse blurry pixels.
What do I need to do to make the Canvas
HiDPI-aware?
(I'm using Qt 5.2.0 beta 1 on Mac OS X 10.8)
Edit: The workaround I came up with was to wrap the Canvas
in an Item
, scale everything up inside onPaint
and then use a transform
on the Canvas
the scale it back down.
Canvas {
id: canvas
x: 0
y: 0
width: parent.width * 2 // really parent.width after the transform
heigth: parent.height * 2 // really parent.height after the transform
/* ... */
// This scales everything down by a factor of two.
transform: Scale {
xScale: .5
yScale: .5
}
onPaint: {
var ctx = canvas.getContext('2d');
ctx.save();
ctx.scale(2, 2) // This scales everything up by a factor of two.
/* ... */
}
}
We used the same trick of doubling the size and then scaling down for the ProgressCircle in qml-material. However, there are a couple improvements you can make:
scale
instead of transform
.Screen.devicePixelRatio
from the QtQuick.Window
module instead of hardcoding the scale factor at 2/0.5.So your code can be simplified to:
Canvas {
property int ratio: Screen.devicePixelRatio
width: parent.width * ratio
heigth: parent.height * ratio
scale: 1/ratio
onPaint: {
var ctx = canvas.getContext('2d');
ctx.save();
ctx.scale(ratio, ratio)
// ...
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With