本文转自安老师的博文:Qt Quick 事件处理之捏拉缩放与旋转

绪论

本文介绍在Android 等智能手机上的一个非常重要的手势:捏拉手势。

捏拉手势最早在苹果手机上得到应用,苹果还曾经尝试为此操作申请专利,借以钳制三星在美国的手机和平板销售。这些我们暂且不管它,咱们只说在 Qt Quick 中如何处理捏拉手势的。

Qt Quick 中的 PinchArea 带来捏拉手势,看名字是不是和 MouseArea 类似?木错,就是酱紫。先来看 PinchArea 都有哪些属性和信号,了解了这些才能使用它。

PinchArea简介

PinchArea 本身是一个不可见的 Item ,通常和一个可见的 Item 配合使用来处理捏拉手势。比如和一个 Rectangle 一块使用,或者和 Image 一块使用实现图片缩放、旋转等效果。捏拉手势识别实际上是通过对若干触摸事件的处理来实现的。

属性

PinchArea 是 Item 的派生类,除了继承自 Item 的属性外,还有两个专属属性: enabledpinch

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方式

qml Code 
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 每个参数的含义,自己设计变换策略。不过好处是,七十二般变化都由你控制。

 qml Code 
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的更多相关文章

  1. PinchArea QML Type

    PinchArea类型是在QtQuick 1.1中添加进去的.PinchArea是一个不可见的对象,常用在与一个可见对象连接在一起,为对应的可见对象提供手势操作.enabled属性被用来去设置绑定对象 ...

  2. qml demo分析(photosurface-图片涅拉)

    阅读qml示例代码已有一小段时间,也陆续的写了一些自己关于qml示例代码的理解,可能由于自己没有大量的qml开发经验,总感觉复杂的ui交互qml处理起来可能会比较棘手,但事实总是会出人意料,今天我们就 ...

  3. qt quick中qml编程语言

    Qt QML 入门 — 使用C++定义QML类型 发表于 2013 年 3 月 11 日   注册C++类 注册可实例化的类型 注册不实例化的QML类型 附带属性 注册C++类 注册可实例化的类型 如 ...

  4. 查看QML数据类型

    assist输入: QML Types A Abstract3DSeries AbstractActionInput AbstractAnimation AbstractAxis AbstractAx ...

  5. QML 从无到有 3 (自动更新)

    新的需求出来啦,需要自动更新功能,不怕程序升级了. 自动更新,QML不好写,需要c++来辅助,这里就涉及QML中调用c++功能(这里就不写了,百度一下,很多). 思路:获取版本>下载程序> ...

  6. QML 从无到有 2 (移动适配)

    随着项目深入,需要移植到安卓上,问题来了,QML安卓适配! 幸好PC端程序和手机屏幕长宽比例相似.虽然单位像素,尺寸不同,通过比例缩放,可以实现组件PC和安卓通用代码. 第一步:定义全局的转换函数(3 ...

  7. QML 从无到有 (基础)

    小公司,没办法,什么都得自己亲自来. 服务端是MVC,现在需要可PC客户端和移动APP. 考虑到网页应用有很多界面框架,可以做出很漂亮的界面来,就尝试着使用nwjs来实现,可是在使用了2天的nwjs后 ...

  8. QML杂记

    1.QML编写可视化元素,运行后程序窗口上无显示.检查电脑的显卡是否支持OpenGL,如果支持请更新显卡驱动. 2.加载图片显示QML Image: Cannot open.解决在qml.qrc右击添 ...

  9. Qml 写的弹出层控件

    QML弹出窗口组件,灯箱效果.动画效果,可拖拽 核心思路:一个mask层,一个最顶层,都用rectangle,禁止事件穿透 使用 Popup { id: popup width: 200; heigh ...

随机推荐

  1. JS高阶---执行上下文

    1.代码分类 2.全局执行上下文 3.函数执行上下文 .

  2. 为什么tcp的TIME_WAIT状态要维持2MSL

    本文主要分析为什么TIME_WAIT状态的持续时间是2MSL而不是1MSL,3MSL或其它的时长,而不会详细描述为什么需要TIME_WAIT状态. 阅读本文需要的预备知识: 了解TCP协议的状态变迁: ...

  3. Linux命令——trap

    简介 trap是shell内置命令,它对硬件信号和其他事件做出响应.trap定义并激活信号处理过程,信号处理过程是当shell接收信号或其他特殊条件时要运行的处理过程. 语法 trap [-lp] [ ...

  4. 三种MPM在工作时的属性

    l  prefork:域fork,一个进程一个请求 l  worker:一个线程一个请求,一个进程生成多个线程 l  event:事件模型,单线程响应多个请求,基于事件驱动 在主配置文件当中,在htt ...

  5. 201871010135 张玉晶《面向对象程序设计(java)》第十六周学习总结

    第一部分:总结教材14.1-14.3知识内容 并发 • 线程的概念 • 中断线程 • 线程状态 • 多线程调度 • 线程同步 一.线程的概念 1. 程序是一段静态的代码,它是应用程序执行的蓝本. 2. ...

  6. 生产者和消费者模型producer and consumer(单线程下实现高并发)

    #1.生产者和消费者模型producer and consumer modelimport timedef producer(): ret = [] for i in range(2): time.s ...

  7. nginx发布静态资源

    nginx发布静态资源 参考 ngx_http_index_module index指令 ngx_http_core_module http指令 location指令 listen指令 root指令 ...

  8. C++面向对象程序设计学习笔记(4)

    类与对象(2) string类 C++不仅向下兼容C的字符表示方法,也声明了一种更方便的字符串类型,即string类. 想要使用string类,必须包括头文件string,即要声明 #include& ...

  9. 配置好运行后Error creating context 'spring.root': Could not load type from string value

    在Webconfig文件的当前项目下引用相关项目

  10. apktool android studio 调试 smali code, 重新打包

    虽然有些菜单的位置跟新版的Android Stuido 3.4 有些不同,但是能用. https://crosp.net/blog/software-development/mobile/androi ...