Search code examples
onclickqml

QML TapHandler: how to ensure only top-most handler gets the events


As I understand it, if you have more than one QML TapHandler covering the same location, they all get the tap event by default; but you can change this behaviour using the grabPermissions property.

In my example, if I click/tap on overlay I want only its TapHandler to get the event. How do I do this?

Here's what I have tried:

Rectangle {
    id: area
    width: 300; height: 300
    color: "yellow"

    TapHandler {
        id: areaTapHandler
        grabPermissions: PointerHandler.ApprovesTakeOverByAnything | PointerHandler.ApprovesCancellation
        onTapped: console.log("Area tapped")
    }
}

Rectangle {
    id: overlay
    x: 50; y: 50
    width: 200; height: 200
    color: "red"

    TapHandler {
        id: overlayTapHandler
        grabPermissions: PointerHandler.CanTakeOverFromAnything
        onTapped: console.log("Overlay tapped")
    }
}

and here's the output:

qml: Overlay tapped
qml: Area tapped

Before anyone asks why I'm not using MouseArea, this is a simplified example and I have many reasons within my real app... and besides that's not the point as I'm asking about TapHandler which is a documented QML component and I want to understand it better.


Solution

  • The default gesturePolicy for TapHandler is TapHandler.DragThreshold. From the documentation, this policy is a passive grab. If you want an exclusive grab, you need to use one of the other gesture policies like TapHandler.WithinBounds.