QObject源码--剩余内容
创始人
2025-05-30 19:20:24
0

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

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

1、QObject的Event事件

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

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

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

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

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

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

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

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

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

 

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

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

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

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

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

b、删除子对象

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

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

 首先检测isDeletingChildren是否为true,如果为true,则触发断言;防止子对象被多次删除;

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

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

c、查找子对象

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

 ​​​​​​  查找相符合的一个对象

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

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

qt_qFindChildren_helper函数

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

3、QTimer相关事件处理

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

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

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

4、moveToThread函数

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

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

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

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

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

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...