-2

I need to create a line like the image below. Does anyone have any suggestions?

target image

In addition to the mentioned image, it is necessary to select the line with the mouse, which can be done with TapHandler.

  • 2
    See this https://stackoverflow.com/questions/31635753/how-to-integrate-a-custom-graphicsitem-into-a-qml-scene/31650722#31650722 – ניר Feb 20 '23 at 07:48
  • 2
    People responded, so I'll just leave you with the option of reviewing the nice repo that created your target image in QML + C++: https://github.com/SC-One/QuickQanava – Another HM Feb 20 '23 at 08:14

1 Answers1

0

[EDIT/REWRITE]

You can consider using Shape, ShapePath for drawing the shadow and the line and you can consider using Image to draw and rotate an SVG arrow head:

import QtQuick
import QtQuick.Controls
import QtQuick.Shapes
Page {
    background: Rectangle { color: "black" }
    ListModel {
        id: line
        Component.onCompleted: {
            for (let pt of [
                { ix: 100, iy: 140 },
                { ix: 150, iy: 160 },
                { ix: 250, iy: 180 },
                { ix: 400, iy: 200 }
            ] )
            append( pt );
        }
    }
    Repeater {
        model: line.count > 1 ? line.count - 1 : 0
        Shape {
            ShapePath {
                startX: line.get(index).ix
                startY: line.get(index).iy
                strokeColor: "#444"
                strokeWidth: 20
                capStyle: ShapePath.RoundCap
                PathLine {
                    x: line.get(index + 1).ix
                    y: line.get(index + 1).iy
                }
            }
        }
    }
    Repeater {
        model: line.count > 1 ? line.count - 1 : 0
        Shape {
            ShapePath {
                startX: line.get(index).ix
                startY: line.get(index).iy
                strokeColor: "white"
                strokeWidth: 3
                capStyle: ShapePath.RoundCap
                PathLine {
                    x: line.get(index + 1).ix
                    y: line.get(index + 1).iy
                }
            }
        }
    }
    Image {
        x: line.get(line.count - 1).ix - width / 2
        y: line.get(line.count - 1).iy - height / 2
        source: "arrow-head.svg"
        cache: false
        transformOrigin: Item.Center
        rotation: Math.atan2(
        line.get(line.count - 1).iy - line.get(line.count - 2).iy,
        line.get(line.count - 1).ix - line.get(line.count - 2).ix
        ) * 180 / Math.PI
    }
    Repeater {
        model: line
        Rectangle {
            x: ix - width / 2
            y: iy - height / 2
            width: 20
            height: 20
            color: "transparent"
            border.color: dragArea.containsMouse || dragArea.drag.active ? "red" : "transparent"
            Drag.active: dragArea.drag.active
            Drag.hotSpot.x: 10
            Drag.hotSpot.y: 10
            onXChanged: Qt.callLater(update)
            onYChanged: Qt.callLater(update)
            MouseArea {
                id: dragArea
                anchors.fill: parent
                drag.target: parent
hoverEnabled: true
            }
            function update() {
                line.setProperty(index, "ix", x + width / 2);
                line.setProperty(index, "iy", y + height / 2);
            }
        }
    }
}

// arrow-head.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<path fill="white" d="M 16 8 L 0 12 L 0 4 z"/> 
</svg>

You can Try it Online!

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75