Насколько я понимаю, если у вас есть более одного QML TapHandler, охватывающего одно и то же местоположение, все они получают событие касания по умолчанию; но вы можете изменить это поведение, используя свойство grabPermissions.
В моем примере, если я нажму overlay, я хочу, чтобы только его TapHandler получило событие. Как мне это сделать?
Вот что я пробовал:
Rectangle {
id: area
width: 300; height: 300
color: "yellow"
TapHandler {
id: areaTapHandler
grabPermissions: PointerHandler.ApprovesTakeOverByAnything | PointerHandler.ApprovesCancellation
onTapped: console.info("Area tapped")
}
}
Rectangle {
id: overlay
x: 50; y: 50
width: 200; height: 200
color: "red"
TapHandler {
id: overlayTapHandler
grabPermissions: PointerHandler.CanTakeOverFromAnything
onTapped: console.info("Overlay tapped")
}
}
и вот результат:
qml: Overlay tapped
qml: Area tapped
Прежде чем кто-нибудь спросит, почему я не использую MouseArea, это упрощенный пример, и у меня есть много причин в моем реальном приложении... и, кроме того, это не тот вопрос, о котором я спрашиваю TapHandler, который является документированным компонентом QML, и я хочу чтобы лучше понять это.





По умолчанию gesturePolicy для TapHandler — TapHandler.DragThreshold. Судя по документации, эта политика представляет собой пассивный захват. Если вы хотите получить эксклюзивный захват, вам нужно использовать одну из других политик жестов, например TapHandler.WithinBounds.
Вы можете подавить другие более низкие уровни TapHandler, если нажаты более высокие TapHandler, например.
Rectangle {
width: 300; height: 300; color: "yellow"
TapHandler {
enabled: !overlayTapHandler.pressed
onTapped: console.info("Area tapped")
}
}
Rectangle {
x: 50; y: 50; width: 200; height: 200; color: "red"
TapHandler {
id: overlayTapHandler
onTapped: console.info("Overlay tapped")
}
}
Вы можете Попробовать онлайн!
Альтернативно, вы можете позволить всем событиям TapHandler.onTapped срабатывать нормально, но реагировать только на первое в последовательности. Мы можем использовать Qt.callLater() как средство фильтрации и реагирования только на первое событие в последовательности:
Rectangle {
width: 300; height: 300; color: "yellow"
TapHandler { onTapped: notify("Area tapped") }
}
Rectangle {
x: 50; y: 50; width: 200; height: 200; color: "red"
TapHandler { onTapped: notify("Overlay tapped") }
}
property bool notifying: false
function notify(str) {
if (notifying) return;
notifying = true;
Qt.callLater(() => {
console.info(str);
notifying = false;
});
}
Вы можете Попробовать онлайн!
Великолепно! Просто и элегантно. Я удалил свои собственные разрешения захвата, поскольку они не нужны при использовании
gesturePolicy: TapHandler.WithinBoundsнаoverlayTapHandler.