Imagine this example:

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.5

Window {
  visible: true
  width: 640
  height: 480
  title: qsTr("Hello World")

  TextField {
    anchors.centerIn: parent
    width: 0.7 * parent.width
  }

  Rectangle {
    width: 30
    height: 30
    anchors.left: parent.left
    anchors.leftMargin: 20
    anchors.top: parent.top
    anchors.topMargin: 20
    color: "blue"

    visible: ma.mouseX < 100 && ma.mouseY < 100
  }

  MouseArea {
    id: ma
    anchors.fill: parent
    hoverEnabled: true
  }
}

So here's the idea. I want the blue rectangle in the upper left corner, to
only appear given some condition based on the X, Y position of the mouse
within the window. Now overlaying the *MouseArea* enables me to *track* the
cursor position at all times. The catch is then, that the *TextField* is
now broken. You cannot click it to give it focus and the cursor doesn't
change when you hover over it, to indicate text input is available.

If I change the ordering and *underlay* the *MouseArea* instead, then the
*TextField* works, but now I loose X, Y tracking, as soon as I'm hovering
over the TextField. I've tried all of:

hoverEnabled: true
preventStealing: true
propagateComposedEvents: true
acceptedButtons: Qt.NoButton

As well as:

mouse.accepted = false;

But it doesn't seem to work as expected.

@Jerome, I think the singleton approach would work, but it feels like
reversing responsibilities, which would lead to some weird patterns down
the road.
@Jason, A dispatch is probably fine for clicks, since they're only run
sporadically. Hover I think is a different thing, and I'd rather keep the
logic triggered to a bare minimum, since it'll be running pretty much
constantly.


/René

On Thu, 21 Mar 2019 at 15:35 Jérôme Godbout <godbo...@amotus.ca> wrote:

> Not sure I get what you are trying to achieve, but having a mouse area
> where the coordinate are local you can map them to global or to an item. If
> the mouse area should not grab the mouse event, make sure to add those to
> your mouse area
>
>
>
> hoverEnabled: true
>
> preventStealing: true
>
> propagateComposedEvents: true
>
> acceptedButtons: Qt.NoButton
>
>
>
> Also do not accept the events if not processing it or the event will be
> stopped (do this for all event that can be accepted):
>
>
>
> onClicked:
>
> {
>
>    mouse.accepted = false;
>
> }
>
>
>
> This should make your overlay mouse area nearly transparent. This way the
> mouseArea overlay known the “global position” and can act upon it and the
> actual behavior under it can process the click like normal.
>
>
>
> You can use a single mouse area that overlay the whole items tree
> (MouseArea into Root Item fill) and change the global coordinate into a Qml
> Singleton. Any part of the application could connect to the coordinate and
> check if the global to whatever item you need match and act according to it.
>
>
>
>
> [image: 36E56279]
>
> une compagnie
>
> RAPPROCHEZ LA DISTANCE
>
> *Jérôme Godbout*
> Développeur Logiciel Sénior /
> Senior Software Developer
>
> *p:* +1 (418) 800-1073 ext.:109
>
> amotus.ca <http://www.amotus-solutions.com/>
> statum-iot.com
>
> <https://www.facebook.com/LesSolutionsAmotus/>
> <https://www.linkedin.com/company/amotus-solutions/>
> <https://twitter.com/AmotusSolutions>
> <https://www.youtube.com/channel/UCoYpQgsmj1iJZyDjTQ3x8Ig>
>
>
>
>
>
> *From:* Interest <interest-boun...@qt-project.org> *On Behalf Of *Jason H
> *Sent:* March 21, 2019 10:11 AM
> *To:* "René Hansen" <ren...@gmail.com>
> *Cc:* interest <interest@qt-project.org>
> *Subject:* Re: [Interest] Track global mouse position in QML
>
>
>
> Please forgive me if I don't completely understand...
>
>
>
> Maybe you want an underlying mouse area, not an overlaynig one? I'd
> suggest you just move the MouseArea in the file.
>
> You can always use an overlaying one and translate the mouse events to the
> child, if there is one. This is what I do for a sample drawing app I have:
>
> In TouchTestRect.qml:
>
>
>
> function dispatchTouchEvent(x,y) {
>
> var c = childAt(x,y);
>
> var typename =  "" + c;
>
> var box;
>
> if (c && (typename.startsWith("QQuickRow") || 
> typename.startsWith("QQuickColumn"))) {
>
>         var point = mapToItem(c, x, y);
>
>         box = c.childAt(point.x, point.y);
>
>         typename =  "" + box;
>
> } else if(typename.startsWith("TouchHitBox_QMLTYPE")) {
>
> ....
>
> }
>
> ...
>
> }
>
>
>
> then:
>
> MouseArea {
>
> anchors.fill: parent
>
> onMouseXChanged: {
>
> touchTestRect.dispatchTouchEvent(mouseX, mouseY)
>
> }
>
> onMouseYChanged: {
>
> touchTestRect.dispatchTouchEvent(mouseX, mouseY)
>
> }
> }
>
> *Sent:* Thursday, March 21, 2019 at 7:50 AM
> *From:* "René Hansen" <ren...@gmail.com>
> *To:* interest <interest@qt-project.org>
> *Subject:* [Interest] Track global mouse position in QML
>
> Hi all,
>
>
>
>
>
> I want to track mouse movement within my entire application window,
> because I need to show/hide/move items around where my cursor is at certain
> times. (Think e.g. custom cursor)
>
> I can do it easily by filling the entire window with a *MouseArea* and
> handle *onPositionChanged*. The problem is that any mouse sensitive
> inputs underneath, then get's blocked by the overlaying *MouseArea*. E.g.
> a *TextField* that is usually highlighted on hover and clickable, no
> longer receives any mouse events.
>
> Is there any straightforward solution to this?
>
> I know *QQuickWindow* has a *mouseMoveEvent*, but that doesn't seem to be
> exposed in QML and if I can avoid subclassing and exposing a custom class,
> I'd rather do that.
>
>
> Cheers,
>
>
>
> René Hansen
>
> _______________________________________________ Interest mailing list
> Interest@qt-project.org https://lists.qt-project.org/listinfo/interest
>
_______________________________________________
Interest mailing list
Interest@qt-project.org
https://lists.qt-project.org/listinfo/interest

Reply via email to