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();
    
    }
    

    }


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.