做了一段时间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. ASP.NET常见命名空间及其功能描述

    命名空间 |  功能描述 System |  包含CLR的基本类型和基类,定义了常用的值类型和引用类型,事件.接口.属性和异常处理等 System.Text | 包含用于文本处理的类,实现了不同编码方 ...

  2. Angular 资料大集合

    https://angular.cn/   Angular 的中文网 http://www.apjs.net/#dir1    Angular 的中文网 http://www.ngnice.com/  ...

  3. oracle查询当前会话数量

    SELECT a.inst_id,sid,username,event,sql_id,a.PROGRAM FROM gv$session a WHERE a.STATUS='ACTIVE' AND u ...

  4. "fcitx按ctrl+space没反应"解决方法

    如果是KDM.GDM.LightDM,打开~/.xprofile.如果是startx.Slim,打开~/.xinitrc.(没有就新建一个) export GTK_IM_MODULE=fcitxexp ...

  5. Vim使用个人心得

    个人最近在Windows上使用gVim 1.移动光标 h,j,k,l 键为左,下,上,右,方向键,控制光标移动,插入状态下不可用,插入状态下,按V键进入查看状态,可使用. 2.进入编辑模式:按 i 键 ...

  6. jenkins和gitlab版本

  7. 【ubantu】在Ubuntu上安装tar.gz,tar.bz以及deb文件(例:libreoffice安装)

    参考文章: https://blog.csdn.net/zhuquan945/article/details/52986712 ==================================== ...

  8. PHP基础知识学习总结

    从今天开始过一遍PHP的基础知识   加油  地址:http://www.runoob.com/php/php-mail.html   该看:PHP发送电子邮件 2017年5月23日23:38:30 ...

  9. 【BZOJ】2186 沙拉公主的困惑

    一道很有价值的题. [解析1]欧几里德算法求乘法逆元,前缀和 [Analysis]O(T n log n). [Sum] ①int运算.假设会超出界,第一个数前要加上(LL)即类型转换. ②gcd不变 ...

  10. mysql慢查询日志分析工具(python写的)

    D:\NormalSoftware>python mysql_filter_slow_log.py ./mysql1-slow.log --no-duplicates --sort-avg-qu ...