自学内容网 自学内容网

Qt触摸事件开发总结

最近对触摸事件比较感兴趣,研究了一下触摸相关的事件,并在此进行整理,不准确的地方希望大家斧正。

言归正传,触摸事件的由来是在手指在触摸设备上的触碰发出的事件。这个很好理解,但是很多朋友稍微深入了解后可能有会有疑问。

  1. QTouchEvent与QGestureEvent的区别,这两种事件的使用场景。
  2. 触摸事件为什么会转换为鼠标事件
  3. 触摸事件转换为鼠标事件是由哪些属性控制的
  4. 如何自定义手势
  5. QTouchEvent的使用方法
  6. QGestureEvent的使用方法
  7. 为什么我的mainwindow只能收到TouchBegin事件,而而无法收到其余的touch事件(例如touchend、touchupdate等)
  8. qt系统中触摸事件、鼠标事件和手势事件是否可以共存。

下面我将一一对上面的问题进行解答。

第一个问题,首先说qt系统中的触摸事件、鼠标事件和手势事件是否可以共存,答案是肯定的,默认情况下qt系统会将触摸事件(touch事件)转换为鼠标事件,也就是说在触摸屏设备的系统中同时存在触摸事件、鼠标事件和手势事件(手势事件需要grabgesture控制,只有调用了grabGesture才可以收到手势事件)。验证方法可以随便写个demo程序进行验证,使用eventFilter方法即可。

第二个问题我编写一个demo,主窗口采用的是mainwindow,centralwidget采用的是默认的。这种情况下centralwidget和mainwindow仅能收到TouchBegin事件,无法收到其余的touch事件。后续通过验证找到了qwdiget如何通过event方法过滤touch相关事件的方法。原因在于对于touchbegin、touchend、touchupdate事件有点类似于连贯的事件,即收到touchbegin事件后event方法需要返回值返回true,后续event方法才能收到touchupdate、touchend等事件;如果直接调用QWidget方法的event则仅能收到TouchBegin事件,这也是之前仅能收到的TouchBegin事件的原因。下面用例子说明问题。

仅能收到TouchBegin事件的情况:

bool QWidget::event(QEvent *event)
{
    if(event->type() == QEvent::TouchBegin
        || event->type() == QEvent::TouchUpdate
        || event->type() == QEvent::TouchEnd)
    {
        qDebug()<<"event type = "<<event->type();
    }
    return QWidget::event(event);
}

能够收到所有事件的例子。

bool QWidget::event(QEvent *event)
{
    if(event->type() == QEvent::TouchBegin
        || event->type() == QEvent::TouchUpdate
        || event->type() == QEvent::TouchEnd)
    {
        qDebug()<<"event type = "<<event->type();
        return true;  //若要在event中过滤到所有的touch事件,此处一定要返回true,告知qt系统
                        //此处touch事件,TouchBegin事件感觉有点类似于开关,只有返回true才能
                        //返回后续的touch事件,例如touchupdate和touchend事件
    }
    return QWidget::event(event);
}

这里对一个QWidget控件如何接收touch事件进行总结:

  1. 首先需要设置属性setAttribute(Qt::WA_AcceptTouchEvents);
  2. 需要重载event方法,并且在该方法中处理touch相关事件时一定要返回true,在touch事件的分支不能采用QWidget默认的event方法

第三个问题触摸事件与鼠标事件的关系。在触摸设备中,触摸屏的触摸事件发送到系统中后,qt系统默认会将触摸事件转换为鼠标事件,但是这并不以为意味着触摸事件消失了,而是在系统中触摸事件、鼠标事件同时存在,如果某个控件打开了手势开关,那么系统将同时存在触摸事件、鼠标事件和手势事件。那哪些属性可以与鼠标事件和触摸事件转换有关系呢?经查证跟两个属性有关。请看下表:

Qt::AA_SynthesizeTouchForUnhandledMouseEventsAll mouse events that are not accepted by the application will be translated to touch events instead.
Qt::AA_SynthesizeMouseForUnhandledTouchEventsAll touch events that are not accepted by the application will be translated to left button mouse events instead. This attribute is enabled by default.

注意上表中的解释是手册中的内容,我通过时间过滤器在我自己的环境上发现触摸事件与互斥事件不是互斥的,但是qt的帮助手册中的的含义却是互斥的含义,这里我持保留意见。有知道原因的朋友可以给我留言

 第四个问题:很多朋友刚开始接触触摸事件可能会有这样的疑问,既然Qt已经提供了QTouchEvent,为什么还会提供QGestureEvent事件呢?反正我刚开始看的时候感觉乱哄哄的,一会儿看到一篇介绍QTouchEvent,一会儿看到QGestureEvent,应该用哪个呢。。。这里我对这两个事件进行分析总结,阐述它们的应用场景。

从层级上来说QTouchEvent相对于QGestureEvent是更底层的事件,QGestureEvent是更高级的封装,QGestureEvent封装的手势类型如下:

TapGesture=1,//轻拍手势。(1个手指单击)
TapAndHoldGesture =2,//轻触并保持(长按)手势。(1个手指单击并长按)
PanGesture=3.//平移手势。(1个手指拖动)
PinchGesture=4,//捏合缩放及缩放(2个手指捏合或转动)
SwipeGesture=5,//滑动手势。(3个手指平移)
CustomGesture=x0100,//可用于测试手势是否为用户定义的手势ID的标志

目前QGestureEvent仅封装了上面的几种手势,当然用户也可以拓展手势。如何拓展这里不进行展开。

而QTouchEvent则相对低级,通过QTouchEvent无法获取手势的情况,只能从事件中获取触摸点的信息,通过实现算法来实现触摸的动作,对比之下,QTouchEvent灵活性更强,触摸控制更精准,对于需要精确触摸控制的需要通过QTouchEvent来实现,例如绘图软件或者游戏等;缺点则是需要根据触摸点的位置自己实现各种算法。对于一些简单的利用手势控制类应用可以使用QGestureEvent来实现,代码量更少,更准确。

第五个问题:触摸事件介绍:

touchstart:触摸开始的时候触发
touchmove : 手指在屏幕上滑动的时候触发
touchend: 触摸结束的时候触发
touchcancel:触摸时由于某些原因被中断时触发

touches:屏幕上所有触摸点的信息
targetTouches:目标区域上所有触摸点的信息
changedTouches:当前事件触摸点的信息

第一根手指触摸屏幕,三个事件获取到的信息是相同的。
第二根手指触摸屏幕,touches会获取两个触摸点的信息,如果触摸点是在同一个目标区域上的targetTouches也是获取到两个触摸点信息,而chengedTouched只保存第二个信息点。
若同时两根手指触摸屏幕,changedTouches会保存两个触摸点信息。
第一个触摸点和最后一个触摸点离开的时候,只有changedTouches才会保存离开的触摸点信息。


原文地址:https://blog.csdn.net/iqanchao/article/details/140656574

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!