做了一段时间linux下与QT事件相关的工作,经常会遇到X11,总是苦于无法完全理解其与linux以及QT事件之间的关系,所以用两篇文章来简单总结下linux中的图形管理和QT事件与X11的关系。

<1> linux中的图形管理

<2> 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将首先被此函数截获。

<1> linux中的图形管理

[GUI] QT事件与X11的关系的更多相关文章

  1. Qt 事件和信号的关系

    Qt的事件是windows的底层消息封装而成的.这个消息和MFC里的消息是同一概念,都是指键盘.鼠标等的按压.松开等消息.例如按下键盘后,windows系统会发出一个 WM_KEYDOWN的消息,Qt ...

  2. c++学习书籍推荐《C++ GUI Qt 4编程(第2版)》下载

    下载地址:点我 百度云及其他网盘下载地址:点我 编辑推荐 <C++ GUI Qt 4编程(第2版)>讲授的大量Qt4编程原理和实践,都可以轻易将其应用于Qt4.4.Qt4.5及后续版本的Q ...

  3. QT事件

    qtevents多线程工作object存储 Another Look at Events(再谈Events) 最近在学习Qt事件处理的时候发现一篇很不错的文章,是2004年季刊的一篇文章,网上有这篇文 ...

  4. qt事件传递过程和处理

    处理监控系统的时候遇到问题,在MainWidget中创建多个子Widget的时候,原意是想鼠标点击先让MainWidget截获处理后再分派给子Widget去处理,但调试后发现如果子Widget重新实现 ...

  5. java Gui编程 事件监听机制

    1.     GUI编程引言 以前的学习当中,我们都使用的是命令交互方式: 例如:在DOS命令行中通过javac java命令启动程序. 软件的交互的方式:   1. 命令交互方式    图书管理系统 ...

  6. Qt 事件机制

    [1]事件 事件是可以被控件识别的操作.如按下确定按钮.选择某个单选按钮或复选框. 每种控件有自己可识别的事件,如窗体的加载.单击.双击等事件,编辑框(文本框)的文本改变事件等等. 事件就是用户对窗口 ...

  7. 详解 QT 源码之 Qt 事件机制原理

    QT 源码之 Qt 事件机制原理是本文要介绍的内容,在用Qt写Gui程序的时候,在main函数里面最后依据都是app.exec();很多书上对这句的解释是,使 Qt 程序进入消息循环.下面我们就到ex ...

  8. QT虚拟小键盘设计--qt事件循环,事件发送的理解

    有人讲到QT5.7及其以后的版本才自带免费的小键盘插件. QT5.10中关于QKeyEvent类:点击打开链接 QT sendEvent和PostEvent, 点击打开链接 my god,我今天安装了 ...

  9. Unity3D研究院编辑器之Editor的GUI的事件拦截

    OnGUI是Unity上一个时代的UI系统,而现在运行时的UI系统已经被UGUI取代,但是Editor的UI还是在用老的这一套GUI系统.比如unity编辑器里的所有窗口,布局,按钮,拖动条.滚动等等 ...

随机推荐

  1. MvcPager 分页示例 — 应用CSS样式

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @model PagedList<string>   <h5>Digg style:</h5> ...

  2. xml格式发送

    1. namespace xml格式发送 { /// <summary> /// 实体转Xml,Xml转实体类 /// </summary> /// <typeparam ...

  3. MVC组件分析

    MVC组件分析   2 System.Web.Mvc V 4.0.0.0 组件分析 2.1 Routing组件(路由选择) Routing的作用就是负责分析Url Action的要求• 必须是一个公有 ...

  4. OSX: 命令行制作U盘Recovery HD

    使用命令行操作,非常easy,可是操作不当非常危急! 免责声明:假设操作不当造成的数据丢失,本人概不负责. 为什么? 不是有OSX恢复磁盘助理嘛?是的.假设仅仅想使用GUI的软件.能够去苹果官方站点: ...

  5. Ubuntu 16.04.5下FFmpeg编译与开发环境搭建

    PC环境: Ubuntu 18.04 上面只要安装下面的提示安装即可,基本上不必再下载依赖库的源代码进行编译和安装 编译步骤: 1, 安装相关工具: sudo apt  install -y auto ...

  6. 自动测试工具agitarOne 初体验之-MockingBird的使用

    大名鼎鼎的AgitarOne就不用解释了,在昨天的随笔中有一些解释,今天主要说说Agitar 中Mockingbird的使用.          为了提高测试代 码的Coverage,仅仅靠Agita ...

  7. linux上复制行到另一个文件

    1.复制3行到5行数据到ab.sh文件,不覆盖ab.sh文件中的已有内容 :3,5w>>ab.sh 2.复制3行到5行数据到ab.sh文件,覆盖ab.sh文件中的已有内容 :3,5w!ab ...

  8. HTML DOM节点的增删改查

    上篇博客中,我们已经初步接触了DOM基础,可是我们学习是为了可以更好地应用,今天我们就来看看DOM节点的增删改查. 无论在哪里,我们想要操作一个东西,总是应该先去获得它.那么我们怎么获得呢? HTML ...

  9. <Netty>(入门篇)TIP黏包/拆包问题原因及换行的初步解决之道

    熟悉TCP编程的读者可能都知道,无论是服务端还是客户端,当我们读取或者发送消息的时候,都需要考虑TCP底层的粘包/拆包机制.木章开始我们先简单介绍TCP粘包/拆包的基础知识,然后模拟一个没有考虑TCP ...

  10. python学习 01 变量

    1.变量不是‘盒子’. 1.1 不同的值,变量名没变,   变量地址也会变. 1.2 相同的值,不同的变量名,变量地址是相同的