Qml Canvas Dashed/Dotted Lines
-
Please help: I'm trying to add custom dashed lines to a QML canvas item. Unfortunately, I'm really struggling with this process. According to the Qt5.5 documentation, the W3C Canvas 2D Context API standard should be covered.
The Context2D API implements the same W3C Canvas 2D Context API standard with some enhanced features.
See: http://doc.qt.io/qt-5/qml-qtquick-context2d.html#details
See: http://www.w3.org/TR/2dcontext/In the example below, I am tying to draw a dotted black rectangle over the dotted white rectangle. Ultimately, I want to be able to draw any path with a custom dash/dot effect. Here is a simplified version of my code:
import QtQuick 2.5 Item { id: mainView anchors.fill: parent Canvas { id: canvas anchors.fill: parent antialiasing: true smooth: true onPaint: { var ctx = canvas.getContext('2d') ctx.save() ctx.clearRect(0, 0, canvas.width, canvas.height) ctx.globalCompositeOperation = "source-over" ctx.lineWidth = 2 ctx.lineWidth /= canvas.scale ctx.strokeStyle = "#ffffffff" ctx.strokeRect(10, 10, 100, 100) ctx.strokeStyle = "#ff000000" /*ctx.createPattern("#ff000000", Qt.Dense5Pattern)*/ ctx.setLineDash([5, 15]) ctx.strokeRect(10, 10, 100, 100) } } }
I get the following error:
TypeError: Property 'setLineDash' of object [object Object] is not a function
As you can see, I tried the createPattern function. However, this really isn't what I want. I need a way to create custom dashed lines.
Please tell me if there is something that I'm missing. I have the newest version of Qt (5.5) using Visual Studio 2013 for my compiler. I'm willing to create classes that inherit Qt classes such as QQuickItem or anything like that, but I need some direction right now.
Thank you in advance to anyone that helps out.
-
I am curious to the response to this, as I had a similar need a few months back. I ended up doing a brute force drawing of the dashed line with the following Component, but would prefer to use patterns as the OP was trying to do.
import QtQuick 2.4
Canvas {
id: canvas
anchors.fill: parent
property real start_x: 0
property real start_y: 0
property real end_x: width
property real end_y: height
property bool dashed: true
property real dash_length: 10
property real dash_space: 8
property real line_width: 2
property real stipple_length: (dash_length + dash_space) > 0 ? (dash_length + dash_space) : 16
property color draw_color: "white"onPaint: { // Get the drawing context var ctx = canvas.getContext('2d') // set line color ctx.strokeStyle = draw_color; ctx.lineWidth = line_width; ctx.beginPath(); if (!dashed) { ctx.moveTo(start_x,start_y); ctx.lineTo(end_x,end_y); } else { var dashLen = stipple_length; var dX = end_x - start_x; var dY = end_y - start_y; var dashes = Math.floor(Math.sqrt(dX * dX + dY * dY) / dashLen); if (dashes == 0) { dashes = 1; } var dash_to_length = dash_length/dashLen var space_to_length = 1 - dash_to_length var dashX = dX / dashes; var dashY = dY / dashes; var x1 = start_x; var y1 = start_y; ctx.moveTo(x1,y1); var q = 0; while (q++ < dashes) { x1 += dashX*dash_to_length; y1 += dashY*dash_to_length; ctx.lineTo(x1, y1); x1 += dashX*space_to_length; y1 += dashY*space_to_length; ctx.moveTo(x1, y1); } } ctx.stroke(); }
}