[GUI] QT事件与X11的关系
做了一段时间linux下与QT事件相关的工作,经常会遇到X11,总是苦于无法完全理解其与linux以及QT事件之间的关系,所以用两篇文章来简单总结下linux中的图形管理和QT事件与X11的关系。
1. Qt中的事件
参考自《C++ GUI Qt 4编程》中第7章给出的Qt事件定义及说明:
Qt的事件(event)是由窗口系统或者Qt自身产生,用以响应所发生的各类事情。当用户按下或者松开键盘或者鼠标上的按键时,就可以产生一个键盘或者鼠标事件;当某个窗口第一次显示的时候,就会产生一个绘制事件,用来告知窗口需要重新绘制它本身,从而使得该窗口可见。大多数事件是作为用户动作的响应而产生的,但也有一些例外,比如timer事件,则是由系统独立产生的。
上面提到的Qt事件的组成,也即按照事件产生的来源进行分类。
|
窗口系统产生 |
在类unix系统中,即X11产生的事件,X server将系统消息放入XEvent队列,并通过socket通知Qt应用程序,Qt事件循环的时候读取这些时间,并转为QEvent。 |
|
Qt自身产生 |
Qt内部自定义的事件,如timer,通过postEvent将事件加入事件队列,等待被分派处理;或者直接sendEvent,直接进行分派处理。 |
我们可以通过Qt中提供了5个级别的事件处理和事件过滤方法,重新定义不同控件(widget)的事件响应。级别越大,可控制的widget越多,权限也就越大。从最高级别到最低级别的事件过滤方法,
|
[1] 派生QApplication并且重新实现notify:Qt调用QApplication::notify来处理一个事件。 [2] 在QApplication对象中安装事件过滤器:在qApp(QApplication的单例对象)中安装事件过滤器(qApp->installEventFilter),应用程序中所有对象的所有事件都将在发送到其它事件过滤器之前,先发送给自定义的eventFilter函数。 [3] 在QObject中安装事件过滤器:在widget对象中安装事件过滤器(widget-> installEventFilter),用户目标对象的所有事件都会首先发送给这个监视对象的eventFilter函数。 [4] 重新实现QObject::event():所有事件在到达特定的事件处理器之前都将通过event函数。 [5] 重新实现特殊的事件处理器:如mousePressEvent、keyPressEvent等。 |
Qt内部的事件处理及过滤流程,可以从这5个级别中清晰地看出,如果还有疑问,可以review下Qt的源代码中QApplication::notify(QObject *receiver, Qevent *e)函数。
2. Qt与X11事件
阅读Qt源代码中与X11事件相关的部分是件相当花费时间和精力的事情,毕竟接触GUI编程的时间很短,所有对于X server如何通过socket通知Qt应用程序?Qt如何将XEvent转换成QEvent?Qt的事件(QPaintEvent)如何响应给X server?以及Qt多线程下的事件循环机制等这些问题将不做细究。
我们从一个Hello Qt开始吧!
#include <QApplication>
#include <QLabel> int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QLabel* label = new QLabel(“Hello Qt!”);
label->show(); return app.exec();
}
每一个Qt的应用程序都要以QApplication::exec()函数结尾,它将开始事件循环(event loop),即主线程的事件循环。这里需要说明下,该事件循环只是一个局部event loop,QDialog::exec()、Qmenu::exec()或者其它线程的exec()都是可以中断QApplication::exec()的。
根据Qt源代码中,事件循环的大致流程如下,

在整个流程中,都需要判断是否有中断退出信号。另外,一个XEvent可能会被翻译(转换)为多个QEvent,比如一个enter事件,XEvent只包含事件的数据,转换为QEvent时,则需要绑定给多个widget(childWidgets、parentWidgets),所以将产生多个QEvent。
在Qt源代码之外,有两种方法可以截获并处理XEvent。其实在事件循环过程中的QEventDispatcherX11::processEvents函数中,存在两个级别的事件处理和过滤过程,第一个就是QApplication::x11EventFilter,可以通过重新实现此函数,截获所有的XEvent;第二个是QWidget::x11Event函数,通过重新实现此函数,发送到该widget的XEvent将首先被此函数截获。
[GUI] QT事件与X11的关系的更多相关文章
- Qt 事件和信号的关系
Qt的事件是windows的底层消息封装而成的.这个消息和MFC里的消息是同一概念,都是指键盘.鼠标等的按压.松开等消息.例如按下键盘后,windows系统会发出一个 WM_KEYDOWN的消息,Qt ...
- c++学习书籍推荐《C++ GUI Qt 4编程(第2版)》下载
下载地址:点我 百度云及其他网盘下载地址:点我 编辑推荐 <C++ GUI Qt 4编程(第2版)>讲授的大量Qt4编程原理和实践,都可以轻易将其应用于Qt4.4.Qt4.5及后续版本的Q ...
- QT事件
qtevents多线程工作object存储 Another Look at Events(再谈Events) 最近在学习Qt事件处理的时候发现一篇很不错的文章,是2004年季刊的一篇文章,网上有这篇文 ...
- qt事件传递过程和处理
处理监控系统的时候遇到问题,在MainWidget中创建多个子Widget的时候,原意是想鼠标点击先让MainWidget截获处理后再分派给子Widget去处理,但调试后发现如果子Widget重新实现 ...
- java Gui编程 事件监听机制
1. GUI编程引言 以前的学习当中,我们都使用的是命令交互方式: 例如:在DOS命令行中通过javac java命令启动程序. 软件的交互的方式: 1. 命令交互方式 图书管理系统 ...
- Qt 事件机制
[1]事件 事件是可以被控件识别的操作.如按下确定按钮.选择某个单选按钮或复选框. 每种控件有自己可识别的事件,如窗体的加载.单击.双击等事件,编辑框(文本框)的文本改变事件等等. 事件就是用户对窗口 ...
- 详解 QT 源码之 Qt 事件机制原理
QT 源码之 Qt 事件机制原理是本文要介绍的内容,在用Qt写Gui程序的时候,在main函数里面最后依据都是app.exec();很多书上对这句的解释是,使 Qt 程序进入消息循环.下面我们就到ex ...
- QT虚拟小键盘设计--qt事件循环,事件发送的理解
有人讲到QT5.7及其以后的版本才自带免费的小键盘插件. QT5.10中关于QKeyEvent类:点击打开链接 QT sendEvent和PostEvent, 点击打开链接 my god,我今天安装了 ...
- Unity3D研究院编辑器之Editor的GUI的事件拦截
OnGUI是Unity上一个时代的UI系统,而现在运行时的UI系统已经被UGUI取代,但是Editor的UI还是在用老的这一套GUI系统.比如unity编辑器里的所有窗口,布局,按钮,拖动条.滚动等等 ...
随机推荐
- springboot整合docker部署(两种构建Docker镜像方式)
项目结构 package hello; import org.springframework.boot.SpringApplication; import org.springframework.bo ...
- angularjs事件传递$on、$emit和$broadcast
如何在作用域之间通信呢? 1.创建一个单例服务,然后通过这个服务处理所有子作用域的通信. 2.通过作用域中的事件处理通信.但是这种方法有一些限制:例如,你并不能广泛的将事件传播到所有监控的作用域中.你 ...
- Android Studio 2.0 正式版公布啦 (首次中文翻译)
Android Studio 2.0 公布了,添加了一些新特性: 1. 更加完好的 Instant Run 2. 更快的 Android Emulator 3.GPU Debugger Preview ...
- servlet文件下载2(单文件下载和批量下载)
使用servlet完毕单文件下载和批量文件下载.批量下载的原理是先将文件打包成zip , 然后再下载. 之前也转载过一篇文件下载的博客,地址:http://blog.csdn.net/ch717828 ...
- DDD架构Sample
http://dddsamplenet.codeplex.com/SourceControl/latest#DDDSample-Vanilla/Application/IBookingService. ...
- JSON解析工具-org.json使用教程
转自:http://www.open-open.com/lib/view/open1381566882614.html 一.简介 org.json是Java常用的Json解析工具,主要提供JSONO ...
- centos6.9使用NTFS-3G挂载ntfs文件系统
centos6.9使用NTFS-3G挂载ntfs文件系统 工作中,难免需要到linux 系统上拷贝文件,但linux 自己不支持ntfs,下面就是解决问题的办法. NTFS-3G是一个开源软件,支持在 ...
- ELK之jason配置nginx文件等多个配置文件
[root@web02 ~]# cat /etc/logstash/conf.d/nginx.conf input { file { path => "/var/log/nginx/a ...
- TBSchedule源码阅读1-TBScheduleManagerFactory
TBSchedule 1 TBScheduleManagerFactory 初始化 成员变量 ZKManager; IScheduleDataManager; Schedule ...
- html5小趣味知识点系列(一)contentEditable
在这里纠正一下某些书籍说 这个修改后的文字内容是无法保存的 的错误必须发送到服务器进行保存才可以(因为我可以保存到内容)看代码吧 也许我理解的不对 <!DOCTYPE html> < ...