afoken has asked for the wisdom of the Perl Monks concerning the following question:
So, I'm once again stuck with a legacy version of QML from Qt 5, Qt 5.9.6 to be exact.
I need to draw a kind of interactive "map" on a touch screen. The map has tens of irregularly shaped areas that ...
The map comes as an SVG file, but I will probably convert it to Javascript code painting on a Canvas object. That solves at least my coloring and labeling problems and leaves only the mouse input problem. Each area needs its own event handler, and clicking on the map background needs to be ignored.
I can only put a single MouseArea into the Canvas, and from its onClicked handler, I need to find the area from the mouse coordinates. There is a method Context2D.isPointInPath(x,y) which looks promising. It works fine if I have just a single area. Adding a second area returns the same, modified object, and so testing mouse coordinates always reports a mouse click on both areas when clicking the second one, and no hit when clicking on the first one.
Obviously, I'm doing something wrong. This is my ugly proof-of-concept test code, with just two square areas on a square map:
Rectangle { x: 0 y: 0 width: 200 height: 200 border.color: "green" border.width: 1 Canvas { anchors.fill: parent property var p1; property var p2; onPaint: { var ctx = getContext("2d"); ctx.reset(); ctx.lineJoin = "round"; ctx.lineCap = "round"; ctx.strokeStyle = "red"; ctx.fillStyle = "blue"; ctx.lineWidth = 1; p1 = ctx.beginPath(); ctx.moveTo(10,10); ctx.lineTo(90,10); ctx.lineTo(90,90); ctx.lineTo(10,90); ctx.closePath(); ctx.stroke(); ctx.fill() ctx.strokeStyle = "green"; ctx.fillStyle = "yellow"; p2 = ctx.beginPath(); ctx.moveTo(110,110); ctx.lineTo(190,110); ctx.lineTo(190,190); ctx.lineTo(110,190); ctx.closePath(); ctx.stroke(); ctx.fill() } MouseArea { anchors.fill: parent onClicked: function(mouse) { console.log("Mouse at "+mouse.x+", "+mouse.y); if (parent.p1) { console.log("Have p1: "+parent.p1); if (parent.p1.isPointInPath(mouse.x, mouse.y)) + { console.log("Hit the red/blue box"); } } else { console.log("Path p1 not set"); } if (parent.p2) { console.log("Have p2: "+parent.p2); if (parent.p2.isPointInPath(mouse.x, mouse.y)) + { console.log("Hit the yellow/green box"); } } else { console.log("Path p2 not set"); } if (parent.p1 === parent.p2) { console.log("Paths are the same"); // <-- this + happens, but should not } } } } }
Of couse, If I had Qt 5.15 available, I would use Shape and PathSvg, and put MouseAreas into the individual Shapes. But all I have is Qt 5.9.6, Shape was introduced in 5.10.
Any hints?
Alexander
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: [OT] QML Canvas Context2D and mouse input
by bliako (Abbot) on Jan 24, 2023 at 09:51 UTC | |
by afoken (Chancellor) on Jan 25, 2023 at 12:09 UTC | |
by afoken (Chancellor) on Jan 26, 2023 at 11:55 UTC |