事件循环与处理过程,是一个gui库的核心。为了能更好的使用qt,写出更好更灵活的代码,我们需要搞明白qt中的事件循环原理。
因为对qt事件处理中,重写QObject::event(QEvent *event)函数,还有一个对象给另一个对象安装事件过滤器,这些函数的返回值到底有什么作用,事件accept(),ignore()到底又是什么作用,对qt的事件循环会产生什么影响呢???
网上的博客搜了一圈,众说纷纭,有的是用小demo测试,有的是从官方文档进行解释的,迟迟有些问题仍然解释不通,因此,我决定,直接找到qt源码,一探究竟,学知识就是要不求甚解,才能让自己得到实际的进步。这也引出了我后这一系列的qt源码解析博客。本博客就是要讲源码的获取与环境准备。
qt自从5.11之后的版本,就不提供安装包下载了,只能在线安装。5.11以及之前的版本的安装包下载:https://download.qt.io/new_archive/ 下面我以qt5.6.1为例。
我们用安装包安装qt时候,其实在安装界面,是可以选择是否安装源码组件的,如果当时没安装的话,按道理说后续在windows的程序和功能,选中这个qt,右键更改,应该是可以重新回到安装时候,增加这个源码组件的,可能提示需要登录qt拿到license。如果行不通,那就重新安装这个qt吧,记得把源码组件给选上就行了。我们可以看到,把所有源码模块都给安装了的。其实我们只需要关注qtbase模块。

在上面那个链接中,进入qt5.6.1文件夹,由于整个源码包太大了(464MB),这里我们只需要最核心的子模块 qtbase即可,里面包含了qt的事件循环,gui等基本库的。但是只有子模块源码,可能没法qt源码级别的正常调试了。


由于qt源码太大了,这里我们只需要打开qtbase中的src目录,直接让qtcreator打开src.pro文件,即可开始阅读代码啦。不然打开整个Src目录作为根节点,qtcreator会卡死的。


按照获取源码方式1,我们把 C:\Qt\Qt5.6.1_1\5.6\Src 这个源码的根目录路径,添加到qtcreator的调试器路径映射中去,就可以了,如下图所示。

调试时候,我们告诉了gdb我们的exe(这个是被调试目标文件,编译时候加了-g选项,因此带了调试信息,里面带了汇编指令,和源文件名、行号的对应关系),给gdb发送一个某文件,某行源码的断点位置信息,gdb就会在对应的汇编指令地址处打一个int 3断点。看我这个博客讲调试断点原理:处理器调试断点原理总结_我是标同学的博客-CSDN博客_调试断点原理
那么这里给qtcreator源码文件夹路径信息后(映射,qtcreator能认识这个路径了),qtcreator就能发送库文件里面的源码行的断点位置给gdb,也能接收到gdb返回的位置信息从而定位到正确的源文件,行号了,然后显示给我们 。
注:因为我们的应用程序是用的qt库(也就是qt的dll,也就是我们常说的qt库)联合我们自己的代码编译得到的,现在通过我们这个过程可以调试了,这说明qt的这些dll里面包含了汇编指令地址和源文件名以及行号映射信息了的,这也叫做debug版的dll,否则就是release版的dll,release版dll由于没有包含调试信息,所以就没法通过我们说的这个过程调试了。除了qt库,其它很多库,都有debug版和release版,比如opencv,还有这个qsci编辑器库(看我博客:QScintilla如何安装和入门(初学者)_我是标同学的博客-CSDN博客_qscintilla)
所以,qt库(qt的所有dll)的版本必须跟我们现在映射的源码版本是一致的(因为qt库就是由这些源码文件编译而来的),否则调试时候qtcreator定位到的行号就会出错了(因为gdb是从qt的dll中拿到行号信息)(当然版本有点儿不一致,但是需要调试的qt源码文件的代码行位置仍然是对的,当然也不会定位出错的)。这里我举个例,把qt源码中前面去掉一行,就会发现断点位置定位就有1行的偏差的。
所以,我们在阅读源码的时候,千万不要去改这些源码文件的内容,否则调试显示会不准确的。
要改也可以,但是不要添加行或者删除行,保证行号位置正确的,也行。因此我们写注释就在后面追加,不要起新行,因为会造成源码的行号改变了。