TapHandler QML Type
点按处理程序更多
| Import Statement: | import QtQuick |
| Inherits: |
属性
- acceptedButtons : flags
- acceptedDevices : flags
- acceptedModifiers : flags
- acceptedPointerTypes : flags
- active : bool
- cursorShape : Qt::CursorShape
- dragThreshold : int
- enabled : bool
- exclusiveSignals : enumeration
(since 6.5) - gesturePolicy : enumeration
- grabPermissions : flags
- longPressThreshold : real
- margin : real
- parent : Item
- point : handlerPoint
- pressed : bool
- tapCount : int
- target : Item
- timeHeld : real
信号
- canceled(eventPoint point)
- doubleTapped(eventPoint eventPoint, Qt::MouseButton button)
- grabChanged(PointerDevice::GrabTransition transition, eventPoint point)
- longPressed()
- singleTapped(eventPoint eventPoint, Qt::MouseButton button)
- tapCountChanged()
- tapped(eventPoint eventPoint, Qt::MouseButton button)
详细说明
TapHandler 是一个处理程序,用于处理触摸屏上的点击或鼠标上的单击。
有效点击手势的检测取决于gesturePolicy 。默认值为 DragThreshold,它要求按下和松开在空间和时间上都很接近。在这种情况下,TapHandler 只需被动抓取即可运行,因此不会干扰其他项目或输入处理程序的事件交付。因此,当您想通过添加带有绑定和/或 JavaScript 回调的 TapHandler 来修改现有控件或项的行为时,默认的gesturePolicy 非常有用。
请注意,按钮(如QPushButton )的实现通常不会考虑按下和松开是否发生在一起:如果按下按钮后改变主意,则需要从按钮边缘一直拖动才能取消点击。在这种情况下,请将gesturePolicy 设置为TapHandler.ReleaseWithinBounds 。
import QtQuick Rectangle { id: button signal clicked property alias text: buttonLabel.text height: Math.max(Screen.pixelDensity * 7, buttonLabel.implicitHeight * 1.2) width: Math.max(Screen.pixelDensity * 11, buttonLabel.implicitWidth * 1.3) radius: 3 property color dark: Qt.darker(palette.button, 1.3) gradient: Gradient { GradientStop { position: 0.0; color: tapHandler.pressed ? dark : palette.button } GradientStop { position: 1.0; color: dark } } TapHandler { id: tapHandler gesturePolicy: TapHandler.ReleaseWithinBounds onTapped: button.clicked() } Text { id: buttonLabel text: "Click Me" color: palette.buttonText anchors.centerIn: parent } }
对于多点手势(双击、三击等),鼠标移动的距离不得超过QStyleHints::mouseDoubleClickDistance() ,触摸移动的距离不得超过QStyleHints::touchDoubleTapDistance() ,两次点击之间的时间间隔不得超过QStyleHints::mouseDoubleClickInterval() 。
另请参阅 MouseArea 和Qt Quick 示例 - 指针处理程序。
属性文档
acceptedButtons : flags
可以激活该指针处理程序的鼠标按钮。
默认情况下,该属性设置为Qt.LeftButton 。可以将其设置为鼠标按钮的 OR 组合,并忽略来自其他按钮的事件。
例如,一个控件可以用两种处理程序以不同方式对左右点击做出响应:
Item { TapHandler { onTapped: console.log("left clicked") } TapHandler { acceptedButtons: Qt.RightButton onTapped: console.log("right clicked") } }
注: 点击触摸屏或点击绘图板上的触控笔可模拟点击鼠标左键。这一行为可通过acceptedDevices 或acceptedPointerTypes 进行更改。
acceptedDevices : flags
可激活该指针处理程序的指向设备类型。
默认情况下,该属性设置为PointerDevice.AllDevices 。如果将其设置为设备类型的 OR 组合,则会忽略来自非匹配设备的事件。
例如,可以使用两个处理程序,以一种方式响应鼠标和手写笔点击,以另一种方式响应触摸屏轻触:
Item { TapHandler { acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus onTapped: console.log("clicked") } TapHandler { acceptedDevices: PointerDevice.TouchScreen onTapped: console.log("tapped") } }
注意: 并非所有平台都能区分鼠标和触摸板;在能区分的平台上,您通常希望鼠标和触摸板的行为相同。
acceptedModifiers : flags
如果设置了该属性,则需要按下给定的键盘修改键才能对指针事件做出反应,否则将忽略它们。
如果该属性设置为Qt.KeyboardModifierMask (默认值),则PointerHandler 会忽略修改键。
例如,Item 可以有两个相同类型的处理程序,其中一个只有在按下所需键盘修饰符时才启用:
Item { TapHandler { acceptedModifiers: Qt.ControlModifier onTapped: console.log("control-tapped") } TapHandler { acceptedModifiers: Qt.NoModifier onTapped: console.log("tapped") } }
如果将acceptedModifiers 设置为修改器按键的 OR 组合,则表示必须按下所有这些修改器才能激活处理程序:
Item { TapHandler { acceptedModifiers: Qt.ControlModifier | Qt.AltModifier | Qt.ShiftModifier onTapped: console.log("control-alt-shift-tapped") } }
可用的修改器如下:
| 常量 | 说明 |
|---|---|
NoModifier | 不允许使用任何修改键。 |
ShiftModifier | 必须按键盘上的 Shift 键。 |
ControlModifier | 必须按键盘上的 Ctrl 键。 |
AltModifier | 必须按下键盘上的 Alt 键。 |
MetaModifier | 必须按下键盘上的 Meta 键。 |
KeypadModifier | 必须按下键盘上的按键。 |
GroupSwitchModifier | 仅限 X11(除非在 Windows 上通过命令行参数激活)。必须按下键盘上的模式切换键。 |
KeyboardModifierMask | 处理程序并不关心按下了哪些修改器。 |
如果需要比多个处理程序和多个修改器标志组合更复杂的行为,可以在 JavaScript 代码中检查修改器:
Item { TapHandler { onTapped: switch (point.modifiers) { case Qt.ControlModifier | Qt.AltModifier: console.log("CTRL+ALT"); break; case Qt.ControlModifier | Qt.AltModifier | Qt.MetaModifier: console.log("CTRL+META+ALT"); break; default: console.log("other modifiers", point.modifiers); break; } } }
另请参见 Qt::KeyboardModifier 。
acceptedPointerTypes : flags
可激活该指针处理程序的指向工具类型(手指、触控笔、橡皮擦等)。
默认情况下,该属性设置为PointerDevice.AllPointerTypes 。如果将其设置为设备类型的 OR 组合,则会忽略来自非匹配devices 的事件。
例如,可以用两种处理程序使一个控件对鼠标、触摸和手写笔的点击作出某种响应,但如果用绘图板上的橡皮擦工具点击,该控件就会自行删除:
Rectangle { id: rect TapHandler { acceptedPointerTypes: PointerDevice.Generic | PointerDevice.Finger | PointerDevice.Pen onTapped: console.log("clicked") } TapHandler { acceptedPointerTypes: PointerDevice.Eraser onTapped: rect.destroy() } }
active : bool [read-only]
只要该输入处理程序通过成功独占一个或多个eventPoints 点,从而独自负责处理一个或多个true 。这意味着该输入处理程序会根据这些事件点的移动更新其属性,并积极操作其target (如有)。
cursorShape : Qt::CursorShape
该属性用于保存鼠标悬停在parent 项目上时显示的光标形状,同时active 是true 。
可用的光标形状有
- Qt.ArrowCursor
- Qt.UpArrowCursor
- Qt.CrossCursor
- Qt.WaitCursor
- Qt.IBeamCursor
- Qt.SizeVerCursor
- Qt.SizeHorCursor
- Qt.SizeBDiagCursor
- Qt.SizeFDiagCursor
- Qt.SizeAllCursor
- Qt.BlankCursor
- Qt.SplitVCursor
- Qt.SplitHCursor
- Qt.PointingHandCursor
- Qt.ForbiddenCursor
- Qt.WhatsThisCursor
- Qt.BusyCursor
- Qt.OpenHandCursor
- Qt.ClosedHandCursor
- Qt.DragCopyCursor
- Qt.DragMoveCursor
- Qt.DragLinkCursor
默认值未设置,允许cursor 的parent 项目出现。可通过将该属性设置为未定义来将其重置为相同的初始状态。
注: 当该属性未设置或已设置为undefined 时,如果读取该值,将返回Qt.ArrowCursor 。
另请参阅 Qt::CursorShape 、QQuickItem::cursor() 和HoverHandler::cursorShape 。
dragThreshold : int
用户必须拖动eventPoint 才能被视为拖动手势的距离(以像素为单位)。
默认值取决于平台和屏幕分辨率。可以通过将其设置为未定义来将其重置为默认值。拖动手势开始时的行为在不同的处理程序中有所不同。
enabled : bool
如果PointerHandler 被禁用,它将拒绝所有事件,也不会发出任何信号。
如果PointerHandler 的parent 为disabled ,即使enabled 属性仍为true ,处理程序也将被禁用。
注意: HoverHandler 的行为有所不同:更多信息请参阅其enabled 属性的文档。
exclusiveSignals : enumeration [since 6.5]
确定singleTapped() 和doubleTapped() 信号的排他性。
| 常数 | 说明 |
|---|---|
NotExclusive | (默认)singleTapped() 和doubleTapped() 分别在用户点击一次或两次时立即发出。 |
SingleTap | singleTapped() 在用户点击一次时立即发出,而doubleTapped() 永远不会发出。 |
DoubleTap | doubleTapped(当用户敲击两次时,()会立即发出,而singleTapped ()则永远不会发出。 |
(SingleTap | DoubleTap) | 这两个信号都会延迟到QStyleHints::mouseDoubleClickInterval() 才发出,因此可以发出singleTapped() 或doubleTapped() ,但不能同时发出。但如果在mouseDoubleClickInterval 内出现 3 个或更多抽头,则两个信号都不会发出。 |
注: 其余信号,如tapped() 和tapCountChanged() 总是立即发出,与此属性无关。
此属性在 Qt 6.5 中引入。
gesturePolicy : enumeration
要识别轻按或长按手势的空间约束条件,以及释放必须在longPressThreshold 计时结束前发生的约束条件。如果不满足这些约束条件,就不会发出tapped 信号,也不会递增tapCount 。如果违反了空间限制,pressed 会立即从真转为假,而不管所持时间的长短。
gesturePolicy 还会影响抓取行为,详情如下。
| 常数 | 说明 |
|---|---|
TapHandler.DragThreshold
按下时抓取:被动 | (默认值)eventPoint 不能有明显移动。如果鼠标、手指或触控笔的移动超过了系统范围内的拖动阈值 (QStyleHints::startDragDistance),即使设备或手指仍然按下,点击手势也会被取消。当TapHandler 需要与其他输入处理程序(例如DragHandler )或事件处理项(例如Qt Quick Controls)合作时,这一策略就会非常有用,因为在这种情况下,TapHandler 不会独占抓取权,而只是一个passive grab 。也就是说,DragThreshold 对于增强现有行为特别有用:即使其他项目或处理程序已经做出反应,甚至可能是在用户界面的不同层中,它也会对点击/单击/长按做出反应。下面的代码段显示了一个TapHandler 在一个组件中的使用情况;但如果我们将该组件的两个实例堆叠起来,就会发现当按压发生在这两个组件上时,这两个组件中的处理程序会同时做出反应,因为被动抓取不会停止事件传播:Item { width: 120; height: 80 component Button : Rectangle { TapHandler { id: tapHandler gesturePolicy: TapHandler.DragThreshold // the default onTapped: tapFlash.start() } } Button { x: 10; y: 10 } Button { x: 30; y: 30 } } |
TapHandler.WithinBounds
按下时抓取:排他 | 如果eventPoint 离开了parent 项目的范围,点击手势将被取消。TapHandler 会在按下时抓取exclusive grab ,但一旦不再满足边界约束条件,就会释放抓取。TapHandler { id: tapHandler gesturePolicy: TapHandler.WithinBounds onTapped: tapFlash.start() } |
TapHandler.ReleaseWithinBounds
按下时抓取:独占 | 释放时(释放鼠标按钮或抬起手指),如果eventPoint 在parent 项目的边界之外,则不会识别点击手势。这与按钮部件的典型行为一致:您可以在按钮外拖动取消点击,也可以在释放前拖回按钮内改变主意。请注意,TapHandler 必须在按下时获取exclusive grab 并保留到松开时才能检测到这一手势。TapHandler { id: tapHandler gesturePolicy: TapHandler.ReleaseWithinBounds onTapped: tapFlash.start() } |
TapHandler.DragWithinBounds
按下时抓取:独家 | 按下时,TapHandler 取exclusive grab ;之后,eventPoint 可以在parent 项的范围内拖动,同时timeHeld 属性继续计数,并且无论拖动距离多远,都会发出longPressed() 信号。不过,与WithinBounds 一样,如果点离开了边界,则轻点手势为canceled() ,active() 变为false ,timeHeld 停止计数。这适用于实现按下-拖动-释放组件,例如菜单,其中单个TapHandler 会检测按下,timeHeld 会驱动 "打开 "动画,然后用户可以拖动到菜单项并释放,同时永远不会离开包含菜单的父场景的边界。此值在 Qt 6.3 中添加。TapHandler { id: menuPopupHandler gesturePolicy: TapHandler.DragWithinBounds onPressedChanged: if (pressed) { menu.x = point.position.x - menu.width / 2 menu.y = point.position.y - menu.height / 2 } else { feedback.text = menu.highlightedMenuItem selectFlash.start() } onCanceled: feedback.text = "canceled" } |
Qt Quick Examples - Pointer Handlers演示了其中的一些用例。
注意: 如果发现TapHandler 的反应与其他行为相冲突,首先应考虑哪个gesturePolicy 是合适的。如果无法通过修改gesturePolicy 来解决,则最好通过调整grabPermissions 来解决某些情况,可以在此处理程序中调整,也可以在其他处理程序中调整,以防止 TapHandler 发生反应。
grabPermissions : flags
该属性指定了当该处理程序的逻辑决定接管独占抓取时,或当该处理程序被其他处理程序要求批准接管或取消抓取时的权限。
| 常数 | 说明 |
|---|---|
PointerHandler.TakeOverForbidden | 此处理程序既不从任何类型的项目或处理程序获取抓取权限,也不向其提供抓取权限。 |
PointerHandler.CanTakeOverFromHandlersOfSameType | 该处理程序可以从另一个同类处理程序处获取独家抓取权限。 |
PointerHandler.CanTakeOverFromHandlersOfDifferentType | 此处理程序可以从任何类型的处理程序获取独占抓取权限。 |
PointerHandler.CanTakeOverFromItems | 该处理程序可以从任何类型的项目中获取独占抓取权。 |
PointerHandler.CanTakeOverFromAnything | 该处理程序可以从任何类型的项目或处理程序中获取独占抓取权。 |
PointerHandler.ApprovesTakeOverByHandlersOfSameType | 该处理程序允许另一个同类处理程序抓取。 |
PointerHandler.ApprovesTakeOverByHandlersOfDifferentType | 该处理程序允许任何类型的处理程序抓取。 |
PointerHandler.ApprovesTakeOverByItems | 该处理程序允许任何类型的物品抓取。 |
PointerHandler.ApprovesCancellation | 此处理程序允许其抓取设置为空。 |
PointerHandler.ApprovesTakeOverByAnything | 该处理程序允许任何类型的项目或处理程序抓取。 |
默认值为PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType | PointerHandler.ApprovesTakeOverByAnything ,允许大多数抓取场景,但可避免两个 PinchHandler 争夺同一个接触点。
longPressThreshold : real
如果eventPoint 的值大于0 ,则必须按下 才能触发长按手势并发出longPressed() 信号的时间(以秒为单位)。如果在此时间限制之前松开点,则可以在满足gesturePolicy 约束条件的情况下检测到点击。如果longPressThreshold 为0 ,则计时器被禁用,不会发出信号。如果longPressThreshold 设置为undefined ,则使用默认值,并可从该属性中读取默认值。
默认值是QStyleHints::mousePressAndHoldInterval() 转换为秒。
margin : real
超出parent 项目边界的余量,在此范围内eventPoint 可以激活此处理程序。例如,在PinchHandler 上,如果target 也是parent ,那么将其设置为至少为典型用户手指宽度一半的距离是非常有用的,这样,如果parent 被缩放到非常小,仍可实现捏合手势。或者,如果基于TapHandler 的按钮放置在屏幕边缘附近,则可用于遵守菲茨定律:即使按钮与屏幕边缘在视觉上相差几个像素,也会对屏幕边缘的鼠标点击做出反应。
默认值为 0。

parent : Item
作为处理程序作用域的Item ;也就是声明该处理程序的 Item。处理程序将代表该 Item 处理事件,这意味着如果指针事件中至少有一个eventPoints 出现在该 Item 的内部,那么该指针事件就是相关的。最初target() 是相同的,但可以重新分配。
另请参见 target 和QObject::parent()。
point : handlerPoint [read-only]
当前正在处理的eventPoint 。如果当前没有正在处理的点,该对象将重置为默认值(所有坐标均为 0)。
pressed : bool [read-only]
当鼠标或触摸点被按下时,pressed 将保持为真,且按下后的任何移动都符合当前的gesturePolicy 。当释放eventPoint 或违反策略时,按下将变为 false。
tapCount : int [read-only]
在规定的时间和空间内,被视为一个手势的点击次数。如果按钮发生变化,计数器将重置为 1。例如,要检测三次点击,可以写入以下内容
Rectangle { width: 100; height: 30 signal tripleTap TapHandler { acceptedButtons: Qt.AllButtons onTapped: if (tapCount == 3) tripleTap() } }
target : Item
该处理程序将处理的项目。
默认情况下,它与parent ,即处理程序所声明的 Item 相同。不过,有时也可以将目标设置为不同的项,以便处理一个项中的事件,但操作另一个项;或者将目标设置为null ,禁用默认行为,而执行其他操作。
timeHeld : real [read-only]
长按点在不超过拖动阈值的情况下保持的时间(以秒为单位)。每渲染一帧至少更新一次,这样就可以渲染一个动画,显示长按触发的动作的进展情况。此外,还可以根据长按时间触发一系列操作。
小于零的值表示该处理程序的Item 中没有按住任何点。
注: 如果gesturePolicy 设置为TapHandler.DragWithinBounds ,则timeHeld 不会停止计数,即使按下点的移动超过了拖动阈值,但只有当点离开parent 项的bounds 时才会停止计数。
信号文档
canceled(eventPoint point)
如果此处理程序已经抓取了给定的point ,则当抓取被其他指针处理程序或项窃取时,将发出此信号。
注: 相应的处理程序是onCanceled 。
doubleTapped(eventPoint eventPoint, Qt::MouseButton button)
当parent 项目在很短的时间(QStyleHints::mouseDoubleClickInterval() )和距离(QStyleHints::mouseDoubleClickDistance() 或QStyleHints::touchDoubleTapDistance() )内被点击两次时,就会发出该信号。该信号总是出现在singleTapped 、tapped 和tapCountChanged 之后。eventPoint 信号参数包含释放事件中有关被点击点的信息,而button 是被点击的mouse button ,或触摸屏上的NoButton 。
注: 相应的处理程序是onDoubleTapped 。
grabChanged(PointerDevice::GrabTransition transition, eventPoint point)
当抓取发生与该处理程序相关的某种变化时,就会发出该信号。
transition (动词)说明发生了什么。point (对象)是被抓取或未被抓取的点。
transition 的有效值是
| 常量 | 说明 |
|---|---|
PointerDevice.GrabExclusive | 该处理程序承担了处理point 的主要责任。 |
PointerDevice.UngrabExclusive | 该处理程序已放弃先前的独家抓取。 |
PointerDevice.CancelGrabExclusive | 该处理程序的独占抓取已被接管或取消。 |
PointerDevice.GrabPassive | 此处理程序已获得被动抓取,以监控point 。 |
PointerDevice.UngrabPassive | 此处理程序已放弃先前的被动抓取。 |
PointerDevice.CancelGrabPassive | 该处理程序之前的被动抓取异常终止。 |
注: 相应的处理程序是onGrabChanged 。
longPressed()
当按住parent 项目的时间超过longPressThreshold 时,就会发出该信号。也就是说,如果您按住一个触摸点或按钮,而任何移动都没有超过拖动阈值,那么在timeHeld 超过longPressThreshold 时,就会发出longPressed 信号。
注: 相应的处理程序是onLongPressed 。
singleTapped(eventPoint eventPoint, Qt::MouseButton button)
当parent 项目被点击一次时,就会发出该信号。经过大于QStyleHints::mouseDoubleClickInterval 的时间后,可以再次点击;但如果距离下一次点击的时间较短,tapCount 将增加。eventPoint 信号参数包含释放事件中关于被点击点的信息,而button 是被点击的mouse button ,或触摸屏上的NoButton 。
注: 相应的处理程序是onSingleTapped 。
tapCountChanged()
当parent 项目被点击一次或多次(在指定的时间和距离范围内),并且当前的tapCount 与之前的tapCount 不同时,就会发出该信号。
注: 相应的处理程序是onTapCountChanged 。
tapped(eventPoint eventPoint, Qt::MouseButton button)
每次点击parent 项目时都会发出该信号。
也就是说,如果您在小于longPressThreshold 的时间段内按下并释放了触摸点或按钮,同时任何移动都没有超过拖动阈值,那么在释放时就会发出tapped 信号。eventPoint 信号参数包含释放事件中有关被点击点的信息,button 是被点击的mouse button ,或触摸屏上的NoButton 。
import QtQuick Rectangle { width: 100 height: 100 TapHandler { acceptedButtons: Qt.LeftButton | Qt.RightButton onTapped: (eventPoint, button)=> console.log("tapped", eventPoint.device.name, "button", button, "@", eventPoint.scenePosition) } }
注: 相应的处理程序是onTapped 。
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.



