触摸处理器 QML 类型

用于触摸事件和点击事件的处理程序。 更多...

导入语句import QtQuick
继承

SinglePointHandler

属性

信号

详细描述

触摸处理器是用于触摸屏上的触摸事件或鼠标上的点击事件的处理程序。

有效轻击手势的检测依赖于 gesturePolicy。默认值是 DragThreshold,要求按下和释放动作在空间和时间上都较为接近。在这种情况下,DragHandler 仅需通过被动捕捉即可工作,因此不会干扰到任何其他项或输入处理器的事件传递。因此,默认的 gesturePolicy 在您想通过添加TapHandler(绑定和/或JavaScript回调)来修改现有控件或项的行为时非常有用。

请注意,按钮(如 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

另请参阅MouseAreaQt Quick 示例 - 指针处理器

属性文档

acceptedButtons : 标志

可以激活此指针处理器的鼠标按钮。

默认情况下,此属性设置为 Qt.LeftButton。它可以将鼠标按钮设置为或操作组合,并忽略其他按钮的事件。

例如,一个控件可以通过两个处理程序以不同的方式响应左键和右键点击

Item {
    TapHandler {
        onTapped: console.log("left clicked")
    }
    TapHandler {
        acceptedButtons: Qt.RightButton
        onTapped: console.log("right clicked")
    }
}

注意: 触摸屏上的轻击或在图形板上使用笔触pression都会模拟点击左鼠标按钮。这种行为可以通过 acceptedDevicesacceptedPointerTypes 来改变。


acceptedDevices : 标志

可以激活此指针处理器的指点设备类型。

默认情况下,此属性设置为 PointerDevice.AllDevices。如果您将其设置为设备类型的或操作组合,它将忽略不匹配的设备的事件。

例如,一个控件可以通过两个处理程序以不同的方式(一个处理鼠标和笔触点击,另一个处理触摸屏轻击)进行响应

Item {
   TapHandler {
       acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad | PointerDevice.Stylus
       onTapped: console.log("clicked")
   }
   TapHandler {
       acceptedDevices: PointerDevice.TouchScreen
       onTapped: console.log("tapped")
   }
}

注意: 并非所有平台都能够区分鼠标和触摸板;对于那些可以区分的平台,您通常想要使鼠标和触摸板的行为相同。


acceptedModifiers : 标志

如果设置此属性,则必须按下指定的键盘修饰符才能对指针事件做出反应,否则忽略它们。

如果将此属性设置为 Qt.KeyboardModifierMask(默认值),则 PointerHandler 会忽略修饰键。

例如,Item 可以有两个相同类型的处理器,其中一个只有在所需的键盘修饰符按下时才启用

Item {
   TapHandler {
       acceptedModifiers: Qt.ControlModifier
       onTapped: console.log("control-tapped")
   }
   TapHandler {
       acceptedModifiers: Qt.NoModifier
       onTapped: console.log("tapped")
   }
}

如果您将 acceptedModifiers 设置为修饰键的或操作组合,这意味着必须按下这些修饰符中的所有修饰符才能激活处理器

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上通过命令行参数激活)。必须按下键盘上的Mode_switch键。
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

此类Pointer Handler可以激活的类型指点设备(手指、笔、橡皮擦等)。

默认情况下,此属性设置为PointerDevice.AllPointerTypes。如果您将其设置为设备类型的或组合,它将忽略来自不匹配的设备的事件。

例如,可以通过两个处理程序,使一个控件以某种方式响应用户的鼠标、触摸和笔点击,但是如果用橡皮擦工具在绘图板上点击,则删除自己。

Rectangle {
   id: rect
   TapHandler {
       acceptedPointerTypes: PointerDevice.Generic | PointerDevice.Finger | PointerDevice.Pen
       onTapped: console.log("clicked")
   }
   TapHandler {
       acceptedPointerTypes: PointerDevice.Eraser
       onTapped: rect.destroy()
   }
}

active : bool [只读]

只要此输入处理程序成功独占捕获一个或多个eventPoints,此值就为true,这样就承担了对此或这些点的唯一处理责任。这意味着它将根据这些点的移动来保持其属性的最新状态,并积极操纵其target(如果有的话)。


cursorShape : Qt::CursorShape

此属性在鼠标悬停在parent项上且activetrue时,将显示光标形状。

可用的光标形状包括

  • 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

默认值未设置,这允许cursorparent项中出现。此属性可以通过将其设置为未定义来重置为其初始条件。

注意:当此属性未设置或已设置为undefined时,读取其值将返回Qt.ArrowCursor

另请参阅: Qt::CursorShapeQQuickItem::cursor() 以及 HoverHandler::cursorShape.


dragThreshold : int

用户必须拖动eventPoint的像素距离,才能将其视为拖动手势。

默认值取决于平台和屏幕分辨率。可以通过将其设置为未定义将其重置为默认值。拖动手势开始时的行为在不同的处理程序中会有所不同。


enabled : bool

如果禁用PointerHandler,它将拒绝所有事件且不会发出任何信号。


exclusiveSignals : 枚举 [自6.5以来]

确定singleTapped() 和 doubleTapped() 信号 exclusive Signals 的唯一性。

常数描述
NotExclusive(默认值) 用户轻触一次或两次时,singleTapped() 和 doubleTapped() 均立即发出。
SingleTap用户轻触一次时,singleTapped() 立即发出,而doubleTapped() 从不发出。
DoubleTap用户轻触两次时,doubleTapped() 立即发出,而singleTapped() 从不发出。
(SingleTap | DoubleTap)两个信号都延迟到 QStyleHints::mouseDoubleClickInterval(),这样singleTapped() 或 doubleTapped() 可以发出,但不能同时发出。但如果在 mouseDoubleClickInterval 内发生 3 次或更多轻触,则两个信号都不会发出。

注意:除了tapped() 和 tapCountChanged() 之外的其他信号,无论这个属性如何,总是立即发出。

此属性自 Qt 6.5 起被引入。


gesturePolicy : 枚举

轻轻触碰或长按手势被识别的空间约束,除在longPressThreshold之前必须释放之外。如果这些约束未满足,则tapped 信号不会发出,且tapCount 不会增加。如果违反空間约束,pressed 从 true 立即转变为 false,无论按住的时间长短如何。

gesturePolicy 还会影响以下所述的抓取行为。

常数描述
TapHandler.DragThreshold

按下时的抓取:passive

(默认值) 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

按下时的抓取:exclusive

如果 eventPoint 离开 parent 项的边界,则轻触手势将被取消。在按下的情况下,TapHandlerexclusive grab,但一旦边界约束不再满足,就会释放抓取。
TapHandler {
    id: tapHandler
    gesturePolicy: TapHandler.WithinBounds
    onTapped: tapFlash.start()
}
TapHandler.ReleaseWithinBounds

按下时的抓取:exclusive

在释放时刻(鼠标按钮释放或手指抬起),如果eventPoint位于parent元素边界之外,则无法识别轻触手势。这对应了按钮小部件的典型行为:可以通过将指针拖出按钮来取消点击,也可以在释放前通过将指针拖回按钮来改变主意。请注意,为了检测这个手势,需要TapHandler在按下时获取独占捕获并将其保留到释放为止。
TapHandler {
    id: tapHandler
    gesturePolicy: TapHandler.ReleaseWithinBounds
    onTapped: tapFlash.start()
}
TapHandler.DragWithinBounds

按下时的抓取:exclusive

在按下时,TapHandler获取独占捕获;之后,可以将eventPoint拖动到parent元素边界内,同时timeHeld属性会持续计算,且无论拖动距离如何,都会发出longPressed()信号。然而,类似于WithinBounds,如果点离开边界,则轻触手势会被取消(),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 示例 - 指针处理器演示了这些用例的使用方法。

注意:如果您发现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,允许大多数接管场景,但避免了例如两个 PinchHandlers 在相同触摸点上互相争夺的情况。


longPressThreshold : real

触发长按手势并发出 longPressed() 信号所需要按下 eventPoint 的秒数。如果该值大于 0。如果在规定时间内点被释放,且 gesturePolicy 约束得到满足,则可以检测到点击。如果 longPressThreshold0,计时器将禁用且不会发出信号。如果 longPressThreshold 被设置为 undefined,则使用默认值,可以从此属性读取。

默认值为 QStyleHints::mousePressAndHoldInterval() 转换为秒。


margin : real

此边缘超出了父项的边界,在此范围内 eventPoint 可以激活此处理器。例如,在 PinchHandler 中,如果 target 也是 parent,将其设置为至少与普通用户手指宽度一半的距离是有用的,这样即使 parent 缩小到非常小的尺寸,捏合手势仍然是可能的。或者,如果基于 TapHandler 的按钮放置在屏幕边缘附近,则可以用来符合菲茨定律:即使按钮在视觉上与边缘隔了几像素,也能对屏幕边缘的鼠标点击作出反应。

默认值是 0。


parent : Item

作为处理程序作用域的 Item;声明它的項目。处理程序将代表此项处理事件,这意味着如果其至少一个 eventPoints 发生在该项的内部,则指针事件是相关的。最初 target() 是相同的,但可以被重新分配。

另请参阅targetQObject::parent


point : handlerPoint [只读]

当前正在处理的 eventPoint。当没有正在处理点时,此对象将重置到默认值(所有坐标都是 0)。


pressed : bool [只读]

当鼠标或触摸点按下,且从按下以来有任何移动都符合当前的 gesturePolicy 时,保持为真。当 eventPoint 释放或策略被违反时,pressed 将更改为 false。


tapCount : int [只读]

在时间和空间约束内发生的点击次数,这些点击被视为单个手势。如果按钮更改,计数器将重置为 1。例如,要检测三连击,可以编写

Rectangle {
    width: 100; height: 30
    signal tripleTap
    TapHandler {
        acceptedButtons: Qt.AllButtons
        onTapped: if (tapCount == 3) tripleTap()
    }
}

target : Item

此处理程序将操作的项目。

默认情况下,它与parent相同,即声明处理器所在的项目项。然而,有时将目标设置为不同的项目项可能会很有用;为了在一个项目项内处理事件但操作另一个项目;或者将目标设置为null,以禁用默认行为并执行其他操作。


timeHeld : real [只读]

按下点在不超过拖拽阈值的情况下保持的时间(秒)。它至少会在每帧渲染时更新一次,这允许渲染显示长按后将被触发的动作的进度的动画。还可能根据按住的时间触发一系列操作。

小于零的值表示在此处理器对应的Item中没有按下点。

注意:如果gesturePolicy设置为TapHandler.DragWithinBounds,则即使按下点移动到拖拽阈值之外,timeHeld也不会停止计数,只有当点离开parent项目项的bounds时才会停止。


信号文档

canceled(eventPoint point)

如果这个处理器已经抓取了指定的point,当不同的Pointer Handler或Item抢走抓取时,将发射此信号。

注意:对应的处理器是onCanceled


doubleTapped(eventPoint eventPoint, Qt::MouseButton button)

gesturePolicy设置为TapHandler.DragWithinBounds,而在较短时间内双击parent项目项,并在短时间内进行移动,则会发射此信号(QStyleHints::mouseDoubleClickInterval()和QStyleHints::mouseDoubleClickDistance()或QStyleHints::touchDoubleTapDistance)。此信号总是在singleTappedtappedtapCountChanged之后出现。信号参数eventPoint包含有关被点击点的释放事件信息,而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()

当父项Item被按下并保持一段时间,且这个时间超过longPressThreshold时,会发出此信号。也就是说,如果你按住一个触摸点或按钮,而任何移动都不超过拖动阈值,那么当timeHeld超过longPressThreshold时,将发出longPressed信号。

注意:相应的处理函数是onLongPressed


singleTapped(eventPoint eventPoint, Qt::MouseButton button)

当父项Item被轻触一次时,会发出此信号。经过一段大于QStyleHints::mouseDoubleClickInterval的时间后,可以再次轻触;但如果两次轻触之间的时间更短,则tapCount会增加。eventPoint信号参数包含有关被轻触点的释放事件的信息,而button是被点击的鼠标按钮,或在触摸屏上的NoButton

注意:相应的处理函数是onSingleTapped


tapCountChanged()

当父项Item被轻触一次或多次(在指定的时距范围内)且当前tapCount与上一tapCount不同时,会发出此信号。

注意:相应的处理函数是onTapCountChanged


tapped(eventPoint eventPoint, Qt::MouseButton button)

每次父项Item被轻触时,都会发出此信号。

也就是说,如果你在小于longPressThreshold的时间周期内按下并释放一个触摸点或按钮,而任何移动都不超过拖动阈值,那么在释放的时刻将发出tapped信号。信号参数eventPoint包含有关被轻触点的释放事件的信息,而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


© 2024 Qt公司有限公司。此处包含的文档贡献是世界各国Qt公司及其分支机构的版权所有物。所提供的文档是根据自由软件基金会发布的GNU自由文档许可协议版本1.3条款许可的。Qt及其相关标志是芬兰和/或其他国家的Qt公司注册的商标。所有其他商标均为其各自所有者的财产。