1

I can paint a line with QML in Qt C++. Please consider the below code:

var trackComponent = Qt.createComponent("track_MapPolyline.qml");
var trackObj = trackComponent.createObject(parent);
trackObj.path = [{1,1}, {2,2}]

and file track_MapPolyline.qml

import QtQuick 2.12
import QtLocation 5.12

MapPolyline
{
    id: track
    line.width: 5
    line.color: "blue"
    smooth: true
    opacity: 0.5
    z:0
}

How can I paint an arrow (--->) in QML?

Abolfazl Diyanat
  • 397
  • 2
  • 13

1 Answers1

3

To draw an arrow I'd recommend to use plain Canvas component, because the Context2D API implements the same W3C Canvas 2D Context API standard with some enhanced features. It means that:

  • you'll be available to draw any other shapes and figures you need,
  • there will be a lot of documentation available,
  • there are lot of solutions and/or "libraries" available to draw on canvas,
  • there are a lot of questions and answers about canvas on StackOverflow already.

Here is an example on how you can draw an arrow that points you to mouse position using Canvas in QML:

Example of running application

import QtQuick 2.0
import QtQuick.Window 2.0

Window {
  id: window
  width: 300
  height: 300
  visible: true
  title: qsTr("Hello Arrow")

  // Aliases declared for ease of usage of valuse in canvas
  property alias mouseX: ma.mouseX
  property alias mouseY: ma.mouseY

  Canvas {
    id: canvas
    anchors.fill: parent

    // Code to draw a simple arrow on TypeScript canvas got from https://stackoverflow.com/a/64756256/867349
    function arrow(context, fromx, fromy, tox, toy) {
      const dx = tox - fromx;
      const dy = toy - fromy;
      const headlen = Math.sqrt(dx * dx + dy * dy) * 0.3; // length of head in pixels
      const angle = Math.atan2(dy, dx);
      context.beginPath();
      context.moveTo(fromx, fromy);
      context.lineTo(tox, toy);
      context.stroke();
      context.beginPath();
      context.moveTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
      context.lineTo(tox, toy );
      context.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
      context.stroke();
    }

    onPaint: {
      // Get the canvas context
      var ctx = getContext("2d");
      // Fill a solid color rectangle
      ctx.fillStyle = Qt.rgba(1, 0.7, 0.1, 1);
      ctx.fillRect(0, 0, width, height);

      // Draw an arrow on given context starting at position (0, 0) -- top left corner up to position (mouseX, mouseY)
      //   determined by mouse coordinates position
      arrow(ctx, 0, 0, mouseX, mouseY)
    }

    MouseArea {
      id: ma
      anchors.fill: parent
      hoverEnabled: true
      // Do a paint requests on each mouse position change (X and Y separately)
      onMouseXChanged: canvas.requestPaint()
      onMouseYChanged: canvas.requestPaint()
    }
  }
}
NG_
  • 6,895
  • 7
  • 45
  • 67