TapHandler: stop propagation
-
I am totally confused as to how tapping do or do not get propagated to "lower" handlers.
Consider following QML:
import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Window 2.12 Window { width: 640 height: 480 visible: true title: qsTr("Hello World") Rectangle { anchors.fill: parent TapHandler { onTapped: console.log("covered tapped") } } // Popup { // visible: true // width: parent.width // height: parent.height Text { // Change this to Button text: "Click me" anchors.fill: parent TapHandler { onTapped: console.log("top tapped") } // } } }
If you click the text, both "top tapped" as well as "covered tapped" is displayed.
I do not want this to happen.
Even if you put the Popup element in between (by uncommented the commented lines), both are displayed.
If you change the "Text" element into "Button", only "top tapped" is displayed.The Button behavior is as expected: if you click a button, you do not want underlying items to get this event too. But I would expect the same with a Popup in between. And I would like to set properties on the top TapHandler to avoid propagation also in the Text case.
I have read and reread the documentation, as well as search the internet, but I do not get a clue as to how to solve this properly.
[I did find other related posts in this forum, but they did not elaborate on the alternative behaviors, and they were not resolved IMO.]
-
I am totally confused as to how tapping do or do not get propagated to "lower" handlers.
Consider following QML:
import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Window 2.12 Window { width: 640 height: 480 visible: true title: qsTr("Hello World") Rectangle { anchors.fill: parent TapHandler { onTapped: console.log("covered tapped") } } // Popup { // visible: true // width: parent.width // height: parent.height Text { // Change this to Button text: "Click me" anchors.fill: parent TapHandler { onTapped: console.log("top tapped") } // } } }
If you click the text, both "top tapped" as well as "covered tapped" is displayed.
I do not want this to happen.
Even if you put the Popup element in between (by uncommented the commented lines), both are displayed.
If you change the "Text" element into "Button", only "top tapped" is displayed.The Button behavior is as expected: if you click a button, you do not want underlying items to get this event too. But I would expect the same with a Popup in between. And I would like to set properties on the top TapHandler to avoid propagation also in the Text case.
I have read and reread the documentation, as well as search the internet, but I do not get a clue as to how to solve this properly.
[I did find other related posts in this forum, but they did not elaborate on the alternative behaviors, and they were not resolved IMO.]
@pieterbekaert
you should accept the tap event in order to stop the propagation.
E.g. add "eventPoint.accepted = true" in the handler -
@raven-worx said in TapHandler: stop propagation:
eventPoint.accepted = true
This does not do the trick.
The accepted property is read-only and "cannot be usefully set from QML"
https://doc.qt.io/qt-5/qml-qtquick-eventpoint.html#accepted-propThere seems to be a "solution" by setting the gesturePolicy on the top TapHandler:
gesturePolicy: TapHandler.ReleaseWithinBounds
This is suggested in
https://interest.qt-project.narkive.com/hd4hqQkH/qml-pointer-handlers-how-to-use-grabpermissions
This IMO if a far from intuitive hack... -
As you already figured out, GrabPermission will do the trick as inteded.
https://doc.qt.io/qt-5/qml-qtquick-taphandler.html#grabPermissions-prop