上一篇《Qt on Android: Qt Quick事件处理之鼠标、键盘、定时器》我们介绍了常见的鼠标、键盘、定时器的处理,鼠标、键盘都是电脑上我们最常使用的事件,这节我们来介绍 Android 智能手机上的一个非常重要的手势:捏拉手势。捏拉手势最早在苹果手机上得到应用,苹果还曾经尝试为此操作申请专利,借以钳制三星在美国的手机和平板销售。这些我们且不管它,咱们只说在 Qt Quick 中如何处理捏拉手势。
广而告之:我正在参加 CSDN 博文大赛,请给我的参赛文章《Qt on Android: Qt Quick 事件处理之信号与槽》投票,谢谢。
Qt Quick 中的 PinchArea 带来捏拉手势,看名字是不是和 MouseArea 类似?木错,就是酱紫。先来看 PinchArea 都有哪些属性和信号,了解了这些才能使用它。
PinchArea简介
PinchArea 本身是一个不可见的 Item ,通常和一个可见的 Item 配合使用来处理捏拉手势。比如和一个 Rectangle 一块使用,或者和 Image 一块使用实现图片缩放、旋转等效果。捏拉手势识别实际上是通过对若干触摸事件的处理来实现的。
属性
PinchArea 是 Item 的派生类,除了继承自 Item 的属性外,还有两个专属属性: enabled 和 pinch 。
enabled 属性默认值为 true ,如果你设置为 false ,那么 PinchArea 就嘛事儿不干,捏拉区域对鼠标、触摸事件就变透明了。
pinch 属性知名与捏拉手势的详情,它是一个组合属性,包括 target 、 active 、 minimumScale 、 maximumScale 、 minimumRotation 、 maximumRotation 、 dragAxis 、 minimumX 、 maximumX 、 minimumY 、 maximumY 等属性。
target 指明捏拉手势要操作的 Item , active (bool类型)属性表示目标 Item 是否正在被拖动。
minimumScale / maximumScale 设置最小、最大缩放系数。 minimuxRotation / maximumRotation 设置对小、最大旋转角度。这四个属性都是 real 类型。
dragAxis 设置沿 X 轴(Pinch.XAxis) 、 Y 轴(Pinch.YAxis) 还是 XY (Pinch.XAndYAxis)两个轴拖动,你也可以禁止拖动,只要给 dragAxis 赋值 Pinch.NoDrag 即可。当 dragAxis 允许拖动时,minimumX / maximumX 设定 X 轴的最小、最大拖动位置, minimumY / maximumY 设定 Y 轴的最小、最大拖动位置。
信号
PinchArea 有三个信号:onPinchStarted() 、 onPinchUpdated() 、 onPinchFinished() 。它们都有一个名为 pinch 的参数,类型是 PinchEvent 。为了有效响应这些信号,必须了解 PinchEvent 类型,我们先介绍它。
PinchEvent 具有下列属性:
- accepted ,在 onPinchStarted() 信号处理器中设置为 true 表明你要响应 PinchEvent ,Qt 会持续发给你更新事件;设置为 false ,Qt 就不会再发 PinchEvent 事件给你了。
- angle ,表示最近两个触点之间的角度, previousAngle 是上一次事件的角度, rotation 是从捏拉手势开始到当前事件的总的旋转角度。
- scale ,表示最近两个触点之间的缩放系数, previousScale 是上一次事件的缩放系数。
- center ,两个触点的中心点, previousCenter 是上一次事件的中心点, startCenter 是事件开始时的中心点。
- point1 , point2 保存当前触点的位置, startPoint1 , startPoint2 保存第二个触点按下时两个触点的位置。
- pointCount 保存到现在为止的触点总数。
onPinchStarted() 信号在第一次识别到捏拉手势时发出,如果你要处理它,那就要将其设置为 true 。然后就可以通过 pinch 参数来设置要变换的 Item 了。
当你在 onPinchStarted() 的信号处理器中接受了 TouchEvent 事件,那么 Qt 就会不断的发送新事件给你, onPinchUpdated() 信号就会不断的发射,你可以在它的信号处理器中通过 pinch 参数,撷取你需要的值来更新你的 Item 。
onPinchFinished() 信号在用户手指离开屏幕时触发。
怎样使用
介绍了 PinchArea 和 PinchEvent ,是时候看看怎么使用它们了。
要想使用 PinchArea 来变换一个 Item ,有两个办法:
- 设定 target 属性,将其指向要变换的 Item ,然后 PinchArea 就会在合适的时候帮你变换它。
- 处理 onPinchStarted() / onPinchUpdated() / onPinchFinished() 信号,在信号处理器中变换目标 Item 。这种方式更灵活,你甚至可以同时处理多个 Item 。
选定一种方式后,你可能还要配置 PinchArea.pinch 属性,给不同的参数设置合理的值,比方说最大可以放大到多少倍。
缩放与旋转实例
这里提供一个简单的使用 PinchArea 的实例,我们用 PinchArea 来旋转和缩放一个矩形。
项目的创建参考《Qt on Android: Qt Quick 之 Hello World 图文详解》,这里不再赘述。
使用 pinch.target
我们先用第一种方式,指定 pinch.target 。直接看 main.qml 文档吧:
import QtQuick 2.0 Rectangle { width: 360; height: 360; focus: true; Rectangle { width: 100; height: 100; color: "blue"; id: transformRect; anchors.centerIn: parent; } PinchArea { anchors.fill: parent pinch.maximumScale: 20; pinch.minimumScale: 0.2; pinch.minimumRotation: 0; pinch.maximumRotation: 90; pinch.target: transformRect; } }
代码很简单,初始化了最小、最大缩放系数,最小、最大旋转角度,然后将 pinch.target 指向 id 为 transformRect 的蓝色矩形。于是,一切都正常运转,两指捏拉之间,缩放与旋转效果就出来了。
图 1 是在 Android 手机上运行的起始效果:
图 1 pinchArea 示例启动效果
图 2 是我两个指头捏拉 了几下后的效果:
图 2 pinchArea 缩放与旋转效果
使用 pinch.target 这种方式,你什么都不用关心,甚至不需要弄明白 pinch 属性到底是什么含义,就可以得到一个不错的变换效果, Qt Quick 默认帮你处理所有的事情。
下面看看使用信号的方式。
使用信号
使用 onPinchStarted() / onPinchUpdated() / onPinchFinished() 要稍微麻烦一些,你必须要了解 PinchEvent 每个参数的含义,自己设计变换策略。不过好处是,七十二般变化都由你控制。
直接看新的 main.qml 文档:
import QtQuick 2.0 Rectangle { width: 360; height: 360; focus: true; Rectangle { width: 100; height: 100; color: "blue"; id: transformRect; anchors.centerIn: parent; } PinchArea { anchors.fill: parent pinch.maximumScale: 20; pinch.minimumScale: 0.2; pinch.minimumRotation: 0; pinch.maximumRotation: 90; onPinchStarted: { pinch.accepted = true; } onPinchUpdated: { transformRect.scale *= pinch.scale; transformRect.rotation += pinch.rotation; } onPinchFinished: { transformRect.scale *= pinch.scale; transformRect.rotation += pinch.rotation; } } }
代码大部分都和 pinch.target 方式一样,只是去掉了 "pinch.target: transformRect" 语句,改用信号处理器。代码很直接,不再解释了。
OK,这篇到此结束。
回顾一下:
- Qt on Android:Qt Quick 简介
- Qt on Android:QML 语言基础
- Qt on Android: Qt Quick 之 Hello World 图文详解
- Qt on Android: Qt Quick 简单教程
- Qt on Android: Qt Quick 事件处理之信号与槽
-
Qt on Android: Qt Quick事件处理之鼠标、键盘、定时器