[转] 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 ...
随机推荐
- SQLAlchemy(4)
结果查询 上节课使用query从数据库中查询到了结果,但是query返回的对象是直接可用的吗? 首先导入模块 from connect import session from user_modules ...
- vs解决方案文件出错
问题描述: 电脑死机,重启电脑后打开解决方案,提示“选择的文件不是有效的解决方案文件” 解决方案: 1. 先用记事本打开这个解决方案查看下,发现其中内容变成空白了? 2. 打开项目中的xxxx.vcx ...
- [笔记] nice-upload 与 nice-static-server
1.request 支持流模式,管道流pipe,抓取图片并保存就很方便了 request('https://s.gravatar.com/avatar/184a1f14c759795b94ae1d01 ...
- 查看tensorflow是否为MKL版本命令
python -c "import tensorflow; print(tensorflow.pywrap_tensorflow.IsMklEnabled())" source a ...
- [RN] React Native ScrollView去掉自带的间隔
React Native ScrollView去掉自带的间隔 使用ScrollView时,自带了一个类似marginTop的效果,将其去掉 <ScrollView automaticallyAd ...
- 【day05】css
一.盒模型(BoxModel) 1.width 宽度 2.height 高度 说明: 块元素和有宽高属性的标记(img,input) 能设置宽度和高度,而行元素不能设置宽高 3 ...
- 徒手实现lower_bound和upper_bound
STL中lower_bound和upper_bound的使用方法:STL 二分查找 lower_bound: ; ; //初始化 l ,为第一个合法地址 ; //初始化 r , 地址的结束地址 int ...
- [LeetCode] 285. Inorder Successor in BST 二叉搜索树中的中序后继节点
Given a binary search tree and a node in it, find the in-order successor of that node in the BST. Th ...
- centos7如何添加开机启动项?
centos7提供开启服务启动的方式: 1.系统服务管理命令,如果是通过yum安装的软件,开机启动脚本,已经自动创建好了,直接执行如下命令 nginx.service后缀可以省略 systemctl ...
- LInux 学习笔记系列
1.Linux 就该这么学的笔记系列