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

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

In reply to [OT] QML Canvas Context2D and mouse input by afoken

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.