Qt Object模型及其线程和事件处理

几个重要结论

QObject、线程和事件处理对象类图如下:
这里写图片描述
大多数Qt类的实现都采用”外部接口类+内部实现类“,即QAbc类作为接口给用户使用,但QAbc类的功能基本上在QAbcPrivate实现。
每个线程都以QThread实例表示,并且在内部拥有一个QThreadData来表示线程的基本数据。
每个线程维护了一个QPostEvent队列,用来保存待处理的事件(如鼠标、键盘以及用户事件),同时每个线程维护了一个QEventLoop栈,但只有栈顶的QEventLoop对象参与当前事件处理

Qt中重要的对象包括:QObject及其派生类对象、线程及其线程对象、事件及事件处理、signal/slot及其connection。
它们之间的关系如下:
**(1)QObject对象可以作为其他QObject的父亲,并其销毁时也会自动销毁所有的子对象。可以在父对象中获取子对象
(2)包括QThread对象在内,每个QObject对象都可以属于一个线程,但QObject与其父对象须属于同一线程,如某对象有父对象或是widget,则不能更换线程
(3)事件处理是基于线程,即如果某个QObject对象不属于线程(如何做到?),则该对象无法参与事件处理
(4)每个QObject对象都有数据结构包含了其所有signals有关的connections,而signal/slots的实现依赖于事件处理**

这里也有几个问题,可进一步思考:
问:QObject对象都是有对应的线程的,但是QThread对象并不属于它产生的线程,而是属于一开始创建QThread对象的线程。这会产生什么问题?
问:QThreadData为何会存在多个QEventLoop?

QObject

所有的Qt对象的基类是QObject,而QObject包含了其内部QObjectPrivate对象(在QObject的构造函数中初始化),QObject的需要的内部成员数据,基本上都放在QObjectPrivate里。Qt内部的类实现,往往会采用XXXClass + XXXClassPrivate机制,包括QObject及其许多派生类,都是如此。所有的XXXPrivate都派生于QObjectData,并提供了在内部QAbc和QAbcPrivate类中互相访问的快捷函数)。体可参见 Qt源码的Private Class实现介绍

QObjectPrivate及其基类QObjectData的关键成员介绍如下:

/* QObjectData */
// 当前QObject 对象的父对象
QObject *parent ;
// 当前QObject 对象的子对象  
QObjectList children;

/* QObjectPrivate */
// 用户输入的数据
ExtraData *extraData ;
// 该对象所属的线程对象   
QThreadData *threadData ;
// 该对象作为 sender的所有 connections
QObjectConnectionListVector *connectionLists ;
// 该对象作为 receiver的所有 connections
Connection *senders ;     
// object currently activating the object
Sender *currentSender ;

从上面代码看,每个QObject都可以有parent和children,当用户在当前对象A构造函数中传入一个B作为父对象时,将当前对象A的parent成员生成B,并在B的children中加入A。当父对象销毁时,它所有的children也将被销毁。

QThreadData是该对象所属的线程对象,在QObject创建时在其构造函数中被设置。
QObjectConnectionListVector作为一个类,派生于QVector

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值