在 Qt 中处理平台相关的底层事件

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

在 Qt 中处理平台相关的底层事件

级别: 中级

涂 波 (tubo@ ), 软件开发工程师, IBM 中国软件开发中心

田 晓燕 (tianxyan@ ), 软件开发工程师, IBM 中国软件开发中心

路 绪清 (luxuqing@ ), 软件开发工程师, IBM 中国软件开发中心

任 谦 (renqian@ ), 软件开发工程师, IBM 中国软件开发中心

2007 年 1 月 28 日

事件是由窗口系统或 Qt 本身对各种事务的反应而产生的。 当用户按下一个键或者鼠标按钮,就会相应产生一个键盘或者鼠标事件。 当窗口第一次显示,会产生一个绘图事件,从而通知最新的可见窗口绘制自身。 使用 Qt 编程时,很少需要考虑事件,因为 Qt 的窗口组件会在事件发生的时候发送信号,然后利用

Signal-Slot 机制进行相应的事件处理。 但是,在编写自定义 Widget 或者需要修改现有Widget 的特性时,或者需要处理平台相关的底层事件时,事件则变得很重要。 本文以 XWindow 平台为例,介绍 Qt 如何处理平台相关的底层事件。 1. Qt 中与平台相关的宏定义

Qt 提供了以下标识系统的宏定义,如表1所示:

表 1. Qt 提供的系统标识宏定义

系统标志

对应的平台

Q_WS_WIN Windows Q_WS_X11 XWindow Q_WS_MAC

Mac

如果项目中调用了平台相关的 APIs ,那么利用条件编译

,使得源程序不用修

文档选项

未显示需要

JavaScript 的文档选项

改,就可以适用于不同的平台。

对于XWindow 平台,代码片断如清单1所示:

清单 1.

#if defined(Q_WS_X11)

//与 XWindow 相关的 native APIs

#endif

对于Windows平台,代码片断如清单2所示:

清单 2.

#if defined(Q_WS_WIN)

//与Windows相关的 native APIs

#endif

对于MAC 平台,代码片断如清单3所示:

清单 3.

#if defined(Q_WS_MAC)

//与Mac相关的native APIs

#endif

2. Xlib 与XEvent

Xlib 是XWindow 提供的API 集合,Xlib 之上是Xt Intrinsics library,Xt 采用面

向对象的设计方法,提供了大量的widgets。在Xt 之上则是各种各样的toolkits,最常用的是Motif。Qt没有对Xt 进行封装,而是直接建立在Xlib 之上。

Xlib 用一个叫"XEvent"的结构来保存从X 服务器那里接收到的事件。Xlib 提供了大量的事件类型。XEvent 包括事件的类型,以及与事件相关的数据。

Qt也定义了一组事件类。其中QEvent 是基类。其他具体事件类,例如QMouseEvent、QKeyEvent、QFocusEvent、QPaintEvent、QMoveEvent、QResizeEvent 等都是从QEvent 继承而来。多数情况下,利用Qt的事件机制,能够满足我们的需求。但是,在某些特定的情况,我们需要能够截获XWindow 的底层事件,并对其进行处理。本文介绍了两种截获XEvent 的方法,一种是重载QApplication 的x11EventFilter() 方法;另一种是重载QWidget 的x11Event() 方法。文中提供的例子基于Qt 4.3,并在Fedora Core 6 上调试通过。

3. QApplication::x11EventFilter() 如何工作

QApplication 类管理Qt应用程序的控制流和主要设置。它包含了主事件循环,对来自窗口系统的所有事件进行处理和调度。它也处理应用程序的初始化和结束,并且提供对话管理。

QApplication 中定义了针对XWindow 平台的虚函数,如清单4所示:

清单 4.

bool QApplication::x11EventFilter ( XEvent * )

创建QApplication 的子类,并且重新实现函数x11EventFilter(),那么所有底层的XEvent 会首先被函数x11EventFilter() 截获。如果希望在函数x11EventFilter() 中针对某事件进行响应,那么在响应结束后返回TRUE,表示该事件不会被分派到QApplication 的Qt主事件循环中。如果函数返回FALSE,那么该事件会被继续分派到QApplication 的Qt主事件循环中,由Qt包装成Qt事件。

此外,针对Windows平台,QApplication 定义了类似的虚函数,如清单5所示:

清单 5.

bool QCoreApplication::winEventFilter ( MSG * msg, long * result )

针对Mac 平台,QApplication 定义了类似的虚函数,如清单6所示:

清单 6.

bool QApplication::macEventFilter ( EventHandlerCallRef caller, EventRef event )

下面通过一个例子说明,如何在Qt中处理XEvent。该例子包括两个可执行程序,一个是xclient,另一个是qtx11filter。xclient 基于Xlib,向qtx11filter 发送XClientMessageEvent。qtx11filter 截获所有的XEvent,但只对XClientMessageEvent 进行处理,将其它所有类型的XEvent 都分派到QApplication 的Qt主事件循环中。

3.1 xclient 的主要流程和源代码

xclient 的主要流程如下:

1.用户通过命令行输入16进制的window ID。

2.向该window ID所在的窗口发送XClientMessageEvent。该事件所携带的数

据是一个长度为4的字符串”2008”。

xclient 的完整源代码xclient.c 如清单7所示:

清单7.

#include

#include

相关文档
最新文档