触摸屏中鼠标事件的捕获和传递及触摸屏的移植

在Linux系统中,如果硬件设备的驱动程序被正确安装,那么在/dev路

径下会有相应的设备文件,它们是对应硬件设备的驱动程序接口,应用程序可以打开这些设备文件,从中读取的数据就对应着硬件设备传回的信息。当鼠标被点击

时,会产生中断并进入中断处理程序,在中断处理程序中,鼠标的动作会被翻译成相应的数据存在一个数据缓冲区中。用户打开设备文件后,就是从这个这个缓冲区

读取数据的。注意,这时的数据是最原始的数据。

当Qt应用程序作为GuiServer运行时,QApplication会创建一个QWSServer*类的指针qwsServer,它是一个全局的指针,在整个Qt应用程序的生命周期都存在,而且只有一个。qwsServer在创建过程中会调用QWSServer::startup(),这个函数会调用QWSServer::openMouse()和QWSServer::openKeyboard()来建立与鼠标和键盘硬件设备的连接。在Qt中,触摸屏作为一种特别的鼠标,具有和鼠标同等的处理方法。

1.openMouse()

它会从环境变量QWS_MOUSE_PROT得到鼠标的类型和设备,它的格式是protocol:device,protocol包括以下的几种:MouseMan,IntelliMouse,Microsoft等,device就是鼠标(或者触摸屏)的设备文件,一般是/dev/mouse,还可能是/dev/ps2(ps类型的鼠标),而对于触摸屏,则会是/dev/Tpanel。最后它会创建一个QWSMouseHandler。

2.QWSMouseHandler* h = newMouseHandler(ms);

newMouseHandler从环境变量字符串中分析出设备文件路径和协议名,然后调用QMouseDriverFactory::create()创建QWSMouseHandler对象。

注:有的qt版本是直接在newMouseHandler()中创建QWSMouseHandler对象

3.QMouseDriverFactory::create(mouseProto, mouseDev)

这个鼠标驱动工厂创建一个指定的QWSMouseHandler对象

4.QWSMouseHandler对象的创建

它会调用自己的数据子对象QWSMouseHandlerPrivate的openDevices()打开鼠标设备文件并进行测试,最后调用QWSMouseHandlerPrivate的notify()将文件描述符(使用open()打开后返回的标志符)和处理函数连接起来。

5.notify(fd)

为设备fd创建一个QSocketNotifier*指针mouseNotifier,并将其activated(int)信号和QWSMouseHandlerPrivate::readMouseData(int)绑定在一起。

这样当设备fd发生中断时,readMouseData(int)会去读取设备缓冲区的内容。这中间有一个桥梁。当应用程序进入主事件循环时,会在循环中不断调用select()来检查文件描述符的变化,检测到变化时会发出QEvent::SockAt事件(通过QApplication::sendEvent()发送)给对应的QSocketNotifier,QSocketNotifier的event()函数中会对数据进行处理并发出activated(int)信号。

6.QWSMouseHandlerPrivate::readMouseData(int)

它先读取数据,得到按下点的坐标,然后调用sendFiltered( pp, Qt::LeftButton )将数据通过信号mouseChanged()发送出去。

如果要判断是否长按,先初始化一个计数器counter用来表示鼠标按下的时间,然后在if ( pressure > 0 ){..}中启动一个定时器,counter++,它表示鼠标还在按下。在if ( pressure < 0 ){…}中停止这个定时器,counter=0。它表示鼠标已经离开触摸屏。

在定时器的slot函数中进行判断,如果counter>0表示鼠标被按下了一段时间,这时就可以发送mouseChanged()信号了,普通状态下发送的信号形如mouseChanged(mousePos, Qt::LeftButton, 0);长按信号就形如emit mouseChanged(mousePos, Qt::MouseLongPress | Qt::LeftButton, 0);

可我们还没定义Qt::MouseLongPress呢?在哪里定义呢?在qnamespace.h中

Qt里原来定义了一个Qt::ButtonState的枚举类型,描述了鼠标和组合键的状态,现在我们对它进行了扩展,让它还可以描述键盘的状态:

enum ButtonState

{

NoButton= 0x0000,

LeftButton= 0x0001,

RightButton= 0x0002,

MidButton= 0x0004,

MouseButtonMask = 0x0007,

ShiftButton= 0x0008,

ControlButton= 0x0010,

AltButton= 0x0020,

KeyButtonMask= 0x0038,

MouseLongPress= 0x0100,

ButtonLongPress = 0x0200,

ReplaceKey= 0x0400,

IMSpecKey= 0x8000,

Keypad= 0x4000

};

mouseChanged()这个信号是绑定在QWSServer* qwsServer上的,slot为setMouse(const QPoint &, int, int它会调用QWSServer的方法QWSServer::sendMouseEvent(const QPoint & p, int state, int wheel)中进行处理的。

7.QWSServer::sendMouseEvent(const QPoint & p, int state, int wheel)

它会创建一个QWSMouseEventevent,并对其进行赋值

event.simpleData.state = state | qws_keyModifiers;

最后调用serverClient->sendEvent(&event);将事件发送给客户端。

8.QWSClient::sendEvent(QWSEvent* e)

当应用程序为多进程时,会将事件写入到socket中,并调用csocket->flush().如果为单进程,则将事件写入到全局队列中qt_client_enqueue(e).客户端收到事件后,会将QWSMouseEvent转化为QWSEvent,转化过程是在QApplication::qwsEventFilter(QWSEvent* e)中进行。

9.QApplication::qwsEventFilter (QWSEvent* e)

所有重QWSServer传回的QWSEvent事件都将在这里进行处理,它先将QWSEvent转化为QEvent,然后使用QApplication::nofity()派发相应的接收窗口。???

当窗口接收到QEvent之后,将其转化为QMouseEvent,其成员函数state()返回的状态就包括我们事先写入的MouseLongPress属性了,简单的使用方式如下:

if(e->state() & Qt::MouseLongPress){…}

到这里,我们可以看出,移植触摸屏的操作主要分为两步,一是将硬件设备安装到Linux系统中,在/dev下能看到相应的设备。二是基于Qt层面的处理,我们需要重新设置QWS_MOUSE_PROT,让它对应步骤一中的设备,然后就是修改动缓冲区读取数据的函数。

从设备缓冲区读取数据的是QWSMouseHandlerPrivate::readMouseData(int),对不同的鼠标设备,readMouseData(int)的内容是不同的。为了方便用户移植不同类型的鼠标,Qt提供了一个基类QWSMouseHandler,不同类型的鼠标从它派生出不同的子类,最后重载它的一些方法(主要是readMouseData(int))即可。这些dd的定义都在qwsmouse_qws.cpp当中。

此外,触摸屏和鼠标有一点的不同的地方,它需要进行调整。因为从设备得到的数据是物理屏的数据,比如s3c2410的触摸屏的ad转换是10位精度,也就是说物理数据从0~1023,在实际的情况中一般是100~1000之间的数据,而我们的液晶屏是640*480(或者是其他的,这和触摸屏的数据没有任何的关系),所以必须将物理数据转换为屏幕上点的数据.他们之间的转换公式,就必须通过定标的方式来确定。

所谓的定标,就是在屏幕上依次出现topleft,bottomleft,bottomright,topright和center一共5个点,用户必须依次在这5个点上点击(在触摸屏上点击,触摸屏就放在液晶屏的上方),这样我们得到了物理的点,也得到了对应的实际的点,因此就可以计算出相应的参数。

如果屏的质量稳定,我们可以将测得的数据放在这个文件当中,并取消掉定标的过程,这样就可以每次使用默认的设置,而不需要重新计算了,通常这些设置会保存在文件/etc/pointercal中。S3c2410的触摸屏驱动是iPAQ兼容的驱动,编译的时候需要定义2个宏:

QWS_MOUSE_IPAQ,QWS_MOUSE_IPAQ_RAW.

同时设定:QWS_MOUSE_PROTO=Tpanel:/dev/h3600_tsraw

linux屏幕触碰事件,触摸屏中鼠标事件的捕获和传递及触摸屏的移植相关推荐

  1. linux屏幕触碰事件,touch事件中的touches、targetTouches和changedTouches详解

    touches: 当前屏幕上所有触摸点的列表; targetTouches: 当前对象上所有触摸点的列表; changedTouches: 涉及当前(引发)事件的触摸点的列表 通过一个例子来区分一下触 ...

  2. WPF 触屏事件后触发鼠标事件的问题及 DataGrid 误触问题

    WPF 触屏事件后触发鼠标事件的问题及 DataGrid 误触问题 目录 一.触屏事件连带触发鼠标事件的问题 二.DataGrid 误触问题及解决方法 独立观察员 2021 年 10 月 10 日 一 ...

  3. java 中鼠标事件_[Java教程]js中鼠标事件总结

    [Java教程]js中鼠标事件总结 0 2017-07-11 00:00:19 js中鼠标事件主要有onclick,onmousedown,onmouseup,oncontextmenu,ondblc ...

  4. 面试题58:javascript中鼠标事件有哪些

    鼠标事件有: 1.click(单击)事件: 2.dblclick(双击)事件: 3.mousedown事件: 4.mouseup事件: 5.mouseout事件: 6.mouseover事件: 7.m ...

  5. js鼠标事件大全-Javascript鼠标事件大全

    js鼠标事件大全-Javascript鼠标事件大全 2009年03月11日 星期三 14:22 鼠标点击事件,多用在某个对象控制的范围内的鼠标点击onDblClick 当键盘上的某个键被按下并且释放时 ...

  6. Javascript中鼠标事件

    鼠标中的几个事件 简单的介绍一下鼠标事件的用法,如当一个注册界面要求录入信息后移开鼠标,后面显示判断录入的信息格式是否正确 <!DOCTYPE html> <html>< ...

  7. Web APIs /APIs --DOM简述/DOM中获取元素方法/事件(含鼠标事件)/操作(含案例)

    Web APIs Web APIs 和 JS 的关联性: Web APIs是 W3C 组织的标准,主要学习DOM 和 BOM Web APIs是 JS 所独有的部分 主要学习页面交互功能 Web AP ...

  8. 14、事件类型(鼠标事件、键盘事件、触屏事件)

    1.鼠标事件 鼠标事件 鼠标移入 onmouseenter 鼠标移出 onmouseleave 鼠标点击 onclick 鼠标移动 onmousemove 2.键盘事件 键盘事件 onkeydown ...

  9. js监听多个事件_JavaScript中的事件与异常捕获解析

    这篇文章主要给大家介绍了关于JavaScript中事件与异常捕获的相关资料,文中通过示例代码介绍的非常详细,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批 ...

  10. echarts y轴添加点击事件_ECharts中的事件和行为

    用户在操作 Echarts 的图表时会触发相应的事件,这些事件由开发者监听,然后回调函数做出相应的处理,可以弹出一个对话框.跳转到一个地址或者做数据下钻等等. ECharts 3 中绑定事件跟 Ech ...

最新文章

  1. Bourne Shell及shell编程
  2. ACM ICPC 2011-2012 Northeastern European Regional Contest(NEERC)A ASCII Area
  3. PHP学习笔记-PHP语言基础3
  4. iOS:ShareSDk的分享
  5. Unity3D中常用的数据结构 学习
  6. spring依赖注入_Spring依赖注入技术的发展
  7. 怎样在IIS下配置PHP
  8. php商家商城,PHP红色小京东多商家入驻商城带移动端运营版
  9. 农村包围城市:企业网站关键词排名上首页
  10. 深度数据 点云数据 激光数据
  11. RPC框架Kitex入门
  12. 笔记③:牛客校招冲刺集训营---C++工程师(5.9 C++新特性)
  13. HTC ONE M7 ROOT后恢复 原始状态(保修)
  14. docker 配置国内镜像地址
  15. 第二十章 Caché 设计模式 职责链模式
  16. Springboot 实现 上传、下载 以及解决必须项目重启才能访问资源的问题
  17. 人工智能数学基础: 11-线性形式与对偶空间
  18. 浅谈PVC塑料配方计算软件的设计
  19. 跟我学SharePoint 2013视频培训课程——探索默认的列表和库(6)
  20. Permission Denial: broadcast from android asks to run as user -2 but is calling from user 0;

热门文章

  1. 心语收集9:如何强大,你仍然是我的弱点。
  2. background简写方式
  3. 【马红“名师+”研修共同体成员风采】
  4. execute immediate使用方法
  5. python爬取某音乐歌词,将内容保存制作词云图
  6. 手把手教你如何连接到宝塔面板创建的FTP空间
  7. 翼支付在Sharding-Sphere项目工作介绍
  8. Android 三方数据库ObjectBox使用
  9. c语言单片机程序段,51单片机C语言编程基础及实例
  10. 双层动态规划_吃土豆问题