徐红伟@百香果科技
QObject类是所有Qt对象的基类。是Qt对象模型的基础。
Signals和Slots机制
signals 和 slots是用于对象间通信的。
signal像(但不是)函数指针,更像C#中的事件,槽就是函数。
signal-slot的功能比函数指针更多,比如可以多对一,和一对多的连接。代价是调用速度略慢。
用QObject的 static method:connect()和disconnect()进行信号和槽的连接/解连接。(这解释了为何使用信号-槽的Class中必须加入Q_OBJECT宏)
自动内存管理
QObjects使用object trees进行自我管理,啥子意思呢?
QObject(QObject *parent= nullptr)
QPushButton(QWidget *parent = nullptr)
QChart::QChart(QGraphicsItem *parent = nullptr, Qt::WindowFlags wFlags = ...)
其实QObject在的构造函数里有个parent参数。如果创建是指定了parent参数,对象就会自动添加到parent的children()列表中。此时parent对象就会接管子对象。就是说parent对象销毁的时候,会自动delete所有子对象,不用怕内存泄露。
这就像一棵大树,只要把根砍了(销毁了),会自动销毁它的枝叶。
其他
当QObject对象被销毁时,会发射 destroyed()信号,可以用之来监测信号的生命周期 。
最后,QObject提供一个定时器QTimer,用于定时。
线程亲和性(Thread Affinity)
QObject 具有线程亲和性,即它存在于特定的线程里。当它接收到 queued signals 或 posted events 时,slots 或 event handlers 在 QObject 所在的线程里运行。(QObject 对象的 slot成员函数在其被创建的线程里运行,而不是发射信号的线程了)。
注意:如果QObject 没有亲和的线程(即 thread() 函数返回 0),则它所在的线程没有运行事件循环,因此它就无法接收到 queued signals或posted events.
默认情况下,QObject生存在创建它的线程下。可以用 thread() 函数查看它所在线程,也可以用 moveToThread()改变所在线程。
所有的 QObjects 都必须和其parent在同一个线程里,因此:
1. 如果两个QObject在不同的线程里,则不能用setParent() 建立父子关系。
2. 当 QObject 移动到另一个线程里后,其所有子对象也自动移动到相同线程。
3.如果QObject有父对象,则对其进行moveToThread()时会失败。
4.如果QObject在 QThread::run()中创建,则它不能成为QThread的子对象,因为QThread不在QThread::run()线程里。
注意:QObject的成员变量不会自动成为其子对象。只有现实调用setParent()或再子对象的构造函数里指定父对象,才能建立父子关系。因此把QObject移动到一个线程时,他的成员变量(非子对象)不会移动。
无拷贝构造函数和=操作
在设计QObject时,特定取消了其拷贝构造函数和=操作。
所在在传递QObjet及其子对象时,要传递指针。在容器类中,也只能存储其指针。
c参考Qt官方文档:“QObejct”
网友评论