QObject源码--剩余内容

QObject中主要的内容是关于信号与槽的管理方式,上一节已做了简单说明,本篇主要看下剩余的部分;

剩余的部分主要是关于对象回收机制、事件处理等内容;

1、QObject的Event事件

QObject源码--剩余内容_第1张图片

通过以上代码可知,QObject中主要有定时器事件,常用的定时器有QTimer,QTime等,后续会着重讲解其使用;timerEvent为虚函数,子类可以实现自定义的函数处理;

 ChildAdded、ChildPolished、ChildRemoved等事件是在其更改其parent对象时,会触发此事件;

DeferredDelete事件:当准备删除此对象时触发;

MetaCall事件:当信号和槽的链接方式为队列时,最终会定位到此事件中

ThreadChange事件:更改为不同线程时触发;

User事件:为自定义事件,如果要捕获自定义事件,可以实现customEvent函数;

EventFilter事件其在QObject实现方式为空,后续会结合QCoreApplication来讲解Qt的事件系统

2、QObject对象管理既对象回收机制:

a、添加子对象到children列表中

 

QObject源码--剩余内容_第2张图片

首先了解下更改QObject对象的parent时,其执行的操作;

如果原parent对象不为空,则判断其是否正在被parent移除,如果已经执行deleteChildren函数则不需要再次在parent中移除;否则在parent的children链表中移除此对象,并发送ChildRemoved事件;

判断新的parent对象和当前对象是否为同一线程,如果不在同一个线程在抛出警告信息,并返回(如果不在同一个线程,则QObject对象内存无法自动被回收,需要手动删除);

将当前对象添加到新的parent对象的children链表中,并发送ChildAdded事件;

最后判断是否需要执行parentChaned函数;parentChanged函数为钩子函数;

b、删除子对象

当QObject对象被删除时,其对应的源码为(主要在析构函数中):

QObject源码--剩余内容_第3张图片

首先删除其子对象,既移除children链表中的对象;如果父对象不为空,将父对象设为空;

QObject源码--剩余内容_第4张图片 首先检测isDeletingChildren是否为true,如果为true,则触发断言;防止子对象被多次删除;

遍历children列表,将currentChildBeingDeleted赋值,更改children[i]为空,删除currentChildBeingDeleted对象;最后将children链表清空,更改对象的标志位;

注意:此地方先调用children[i]取出带删除的对象,然后将children[i]赋值为0,再删除此在对象;这样做应该是防止待删除对象执行其析构函数时消耗时间太长,而此时又执行了setParent方法时会引起异常(删除的对象又再次被添加到其他对象的children列表中,可以结合setParent方法理解)。

c、查找子对象

查找对象一般又2种方式,一种是查找一个对象,一种是查找所有相符的对象列表

 QObject源码--剩余内容_第5张图片​​​​​​  查找相符合的一个对象

首先移除T对象的const、volatile、*等关键字,提取对象的原始类型;然后调用qt_qFindChild_helper函数。

QObject源码--剩余内容_第6张图片

 遍历children列表,查找子对象中和T对象有继承关系的对象,且name为空或者和objectName相匹配时,既返回当前对象;如果再当前children列表中没有找到,且option为递归查找,则在子对象中查找。

qt_qFindChildren_helper函数

QObject源码--剩余内容_第7张图片

遍历children列表,查找子对象中是否和当前对象相匹配,如果相符,则添加到list列表中;

3、QTimer相关事件处理

QObject源码--剩余内容_第8张图片

启动定时器,主要调用eventDispatcher对象,注册一个定时器事件,并保存对应的定时器id到runningTimers中;

QObject源码--剩余内容_第9张图片

 停止定时器,主要是调用事件分发器的unregisterTimer函数,并在runningTimers中移除对应的定时器;

后续分析QEventDispatcher函数时,会具体查看registerTimer及unRegisterTimer函数,猜测是调用windows及unix系统的api实现定时器事件的分发;

4、moveToThread函数

QObject源码--剩余内容_第10张图片moveToThread函数主要有:1、遍历所有子对象并发送线程改变事件;2、将当前postEventList中待分发的事件转移到新的线程中;3、更改当前信号槽列表,将其存储的threadData信息调整为目标threadData;主要在setThreadData_helper中实现如下:

QObject源码--剩余内容_第11张图片

 上图1:转移event事件到新的线程中

上图2:如果作为信号发送者,清空所有的信号接收者

上图3:如果作为信号接收者,调整发送信号对象中存储的线程信息(将threadData信息更改为目标线程信息)

最后循环遍历所有的子对象,并调整线程信息;

你可能感兴趣的:(qt,开发语言,学习)