[转] QML PinchArea
本文转自安老师的博文:Qt Quick 事件处理之捏拉缩放与旋转
绪论
本文介绍在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 保存到现在为止的触点总数。
oPinchStarted() 信号在第一次识别到捏拉手势时发出,如果你要处理它,那就要将其设置为 true 。然后就可以通过 pinch 参数来设置要变换的 Item 了。
当你在 onPinchStarted() 的信号处理器中接受了 TouchEvent 事件,那么 Qt 就会不断的发送新事件给你, onPinchUpdated() 信号就会不断的发射,你可以在它的信号处理器中通过 pinch 参数,撷取你需要的值来更新你的 Item 。
onPinchFinished() 信号在用户手指离开屏幕时触发。
怎样使用
介绍了 PinchArea 和 PinchEvent,是时候看看怎么使用它们了。
想使用 PinchArea 来变换一个 Item,有两个办法:
设定 target 属性,将其指向要变换的 Item ,然后 PinchArea 就会在合适的时候帮你变换它。
处理 onPinchStarted() / onPinchUpdated() / onPinchFinished() 信号,在信号处理器中变换目标 Item 。这种方式更灵活,你甚至可以同时处理多个 Item 。
选定一种方式后,你可能还要配置 PinchArea.pinch 属性,给不同的参数设置合理的值,比方说最大可以放大到多少倍。
缩放与旋转实例
pinch.target方式
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Rectangle {
width: ; height: ; focus: true; Rectangle { width: ; height: ; color: "blue"; id: transformRect; anchors.centerIn: parent; } PinchArea { anchors.fill: parent pinch.maximumScale: ; pinch.minimumScale: ; pinch.minimumRotation: ; pinch.maximumRotation: ; pinch.target: transformRect; } } |
代码很简单,初始化了最小、最大缩放系数,最小、最大旋转角度,然后将 pinch.target 指向 id 为 transformRect 的蓝色矩形。于是,一切都正常运转,两指捏拉之间,缩放与旋转效果就出来了。
使用 pinch.target 这种方式,你什么都不用关心,甚至不需要弄明白 pinch 属性到底是什么含义,就可以得到一个不错的变换效果, Qt Quick 默认帮你处理所有的事情。
下面看看使用信号的方式。
使用信号
使用 onPinchStarted() / onPinchUpdated() / onPinchFinished() 要稍微麻烦一些,你必须要了解 PinchEvent 每个参数的含义,自己设计变换策略。不过好处是,七十二般变化都由你控制。
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
Rectangle { width: ; height: ; focus: true; Rectangle { width: ; height: ; color: "blue"; id: transformRect; anchors.centerIn: parent; } PinchArea { anchors.fill: parent pinch.maximumScale: ; pinch.minimumScale: ; pinch.minimumRotation: ; pinch.maximumRotation: ; 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" 语句,改用信号处理器。代码很直接,不再解释了。
[转] QML PinchArea的更多相关文章
- PinchArea QML Type
PinchArea类型是在QtQuick 1.1中添加进去的.PinchArea是一个不可见的对象,常用在与一个可见对象连接在一起,为对应的可见对象提供手势操作.enabled属性被用来去设置绑定对象 ...
- qml demo分析(photosurface-图片涅拉)
阅读qml示例代码已有一小段时间,也陆续的写了一些自己关于qml示例代码的理解,可能由于自己没有大量的qml开发经验,总感觉复杂的ui交互qml处理起来可能会比较棘手,但事实总是会出人意料,今天我们就 ...
- qt quick中qml编程语言
Qt QML 入门 — 使用C++定义QML类型 发表于 2013 年 3 月 11 日 注册C++类 注册可实例化的类型 注册不实例化的QML类型 附带属性 注册C++类 注册可实例化的类型 如 ...
- 查看QML数据类型
assist输入: QML Types A Abstract3DSeries AbstractActionInput AbstractAnimation AbstractAxis AbstractAx ...
- QML 从无到有 3 (自动更新)
新的需求出来啦,需要自动更新功能,不怕程序升级了. 自动更新,QML不好写,需要c++来辅助,这里就涉及QML中调用c++功能(这里就不写了,百度一下,很多). 思路:获取版本>下载程序> ...
- QML 从无到有 2 (移动适配)
随着项目深入,需要移植到安卓上,问题来了,QML安卓适配! 幸好PC端程序和手机屏幕长宽比例相似.虽然单位像素,尺寸不同,通过比例缩放,可以实现组件PC和安卓通用代码. 第一步:定义全局的转换函数(3 ...
- QML 从无到有 (基础)
小公司,没办法,什么都得自己亲自来. 服务端是MVC,现在需要可PC客户端和移动APP. 考虑到网页应用有很多界面框架,可以做出很漂亮的界面来,就尝试着使用nwjs来实现,可是在使用了2天的nwjs后 ...
- QML杂记
1.QML编写可视化元素,运行后程序窗口上无显示.检查电脑的显卡是否支持OpenGL,如果支持请更新显卡驱动. 2.加载图片显示QML Image: Cannot open.解决在qml.qrc右击添 ...
- Qml 写的弹出层控件
QML弹出窗口组件,灯箱效果.动画效果,可拖拽 核心思路:一个mask层,一个最顶层,都用rectangle,禁止事件穿透 使用 Popup { id: popup width: 200; heigh ...
随机推荐
- LNK2001 无法解析的外部符号 __imp__CameraCreateSettingPage@24
用VS2017,Release X86进行编译时显示如下错误: 1>CWDMDlg.obj : error LNK2001: 无法解析的外部符号 __imp__CameraGetImageBuf ...
- c# 第三节 vs的安装
本节内容: 学会安装vs 一:下载 地址:http://down.lansedongli.com/view/30323.html 二.vs2015支持的操作系统 三.vs2015的硬件要求 四.安装 ...
- 201871010106-丁宣元 《面向对象程序设计(java)》第七周学习总结
201871010106-丁宣元 <面向对象程序设计(java)>第七周学习总结 正文开头: 项目 内容 这个作业属于哪个课程 https://home.cnblogs.com/u/nwn ...
- MyBatis 使用 foreach 批量插入
MyBatis 使用 foreach 批量插入 参考博文 老司机学习MyBatis之动态SQL使用foreach在MySQL中批量插入 使用MyBatis一次性插入多条数据时候可以使用 <for ...
- AWS云教育账号创建以及搭建数据库
注册过程繁琐,本文强调关键几点 首先拿到aws的二维码,进入之后填写相关个人信息,用学校邮箱注册,用学校邮箱注册!! 之后审核会有大约10分钟的过程,之后会收到确认邮件 点进去之后就可以设置自己的密码 ...
- B1001 害死人不偿命的(3n+1)猜想 (15 分)
一.参考代码: #include<iostream> using namespace std; int main(){ int n; int step = 0; cin >> ...
- AtCoder Grand Contest 037 简要题解
从这里开始 题目目录 Problem A Dividing a String 猜想每段长度不超过2.然后dp即可. 考虑最后一个长度大于等于3的一段,如果划成$1 + 2$会和后面相同,那么划成$2 ...
- 多线程避免使用SimpleDateFormat及替代方案
先来看一个多线程下使用例子,看到运行结果会出现异常: import java.text.DateFormat; import java.text.SimpleDateFormat; import ja ...
- 微信JSSDK 扫描二维码
<?php require_once('wxjssdk.class.php'); $weixin = new class_weixin(); $signPackage = $weixin-> ...
- Docker底层原理介绍
1.docker介绍 1.1什么是docker Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻 ...