关于Qt中信号和槽的Connection
来源:互联网 发布:好看的宫廷小说知乎 编辑:程序博客网 时间:2024/06/05 11:26
本文主要对我翻译的那篇博文中关于connection的建立过程做一些补充说明(那篇博文在这儿:http://blog.csdn.net/newthinker_wei/article/details/22785763)。
下面先看几个重要的成员变量和几个数据类型(类或结构体)的定义。
class Q_CORE_EXPORT QObjectPrivate : public QObjectData{ ...... ...... // QObjectPrivate中的几个结构体类型的定义: struct Connection { QObject *sender; QObject *receiver; ...... ...... // The next pointer for the singly-linked ConnectionList Connection *nextConnectionList; //senders linked list Connection *next; Connection **prev; ...... ...... ushort method_offset; ushort method_relative; uint signal_index : 27; // In signal range (see QObjectPrivate::signalIndex()) ushort connectionType : 3; // 0 == auto, 1 == direct, 2 == queued, 4 == blocking ushort isSlotObject : 1; ushort ownArgumentTypes : 1; ...... int method() const { return method_offset + method_relative; } ...... }; // ConnectionList is a singly-linked list struct ConnectionList { ConnectionList() : first(0), last(0) {} Connection *first; Connection *last; }; struct Sender { QObject *sender; int signal; int ref; }; ...... ...... // QObjectPrivate中的几个重要成员变量的定义: QObjectConnectionListVector *connectionLists; // QObjectConnectionListVector的定义在下一段代码中给出。 // QObjectConnectionListVector是以QObjectPrivate::ConnectionList为基础类型的 // Vector容器。每一个ConnectionList有一个first和一个last指针。 /* This vector contains the all connections from an object. Each object may have one vector containing the lists of connections for a given signal. The index in the vector correspond to the signal index. The signal index is the one returned by QObjectPrivate::signalIndex (not QMetaObject::indexOfSignal). Negative index means connections to all signals. This vector is protected by the object mutex (signalSlotMutexes()) Each Connection is also part of a 'senders' linked list. The mutex of the receiver must be locked when touching the pointers of this linked list. */ Connection *senders; // linked list of connections connected to this object Sender *currentSender; // object currently activating the object ...... ......};
QObjectConnectionListVector的定义:
class QObjectConnectionListVector : public QVector<QObjectPrivate::ConnectionList> { public: bool orphaned; //the QObject owner of this vector has been destroyed while the vector was inUse bool dirty; //some Connection have been disconnected (their receiver is 0) but not removed from the list yet int inUse; //number of functions that are currently accessing this object or its connections QObjectPrivate::ConnectionList allsignals; QObjectConnectionListVector() : QVector<QObjectPrivate::ConnectionList>(), orphaned(false), dirty(false), inUse(0) { } QObjectPrivate::ConnectionList &operator[](int at) { if (at < 0) return allsignals; return QVector<QObjectPrivate::ConnectionList>::operator[](at); } };
可见QObjectConnectionListVector是从QVector模板类继承而来。这里不再贴出QVector的定义,只给出QtAssistant中对QVector模板类的介绍:
The QVector class is a templateclass that provides a dynamic array.
QVector<T> is one of Qt'sgeneric containerclasses. It stores its items in adjacent(相邻的)memory locations and provides fast index-based access.
看了上面几个定义,现在可以了解connect和disconnect的过程了。
每个QObject对象都有一个QObjectConnectionListVector结构,这是一个Vector容器,它里面的基本单元都是ConnectionList类型的数据,ConnectionList的个数与该QObject对象的signal个数相同。每个ConnectionList对应一个信号,它记录了连接到这个信号上的所有连接。前面已经看到ConnectionList的定义中有两个重要成员:first和last,他们都是Connection 类型的指针,分别指向连接到这个信号上的第一个和最后一个连接。所有连接到这个信号上的连接以单向链表的方式组织了起来,Connection结构体中的nextConnectionList成员就是用来指向这个链表中的下一个连接的。
同时,每个QObject对象还有一个senders成员,senders是一个Connection类型的指针,senders本身也是一个链表的头结点,这个链表中的所有结点都是连接到这个QObject对象上的某个槽的连接。不过这个链表跟上一段提到的链表可不是同一个!虽然他们可能有一些共同结点!下面详细说明。
每一个Connection对象都同时处于两个链表当中。其中一个是以Connection的nextConnectionList成员组织起来的单向链表,这个单项链表中每个结点的共同点是,他们都依赖于同一个QObject对象的同一个信号,这个链表的头结点就是这个信号对应的ConnectionList结构中的first;另一个链表是以Connection的next和prev成员组织起来的双向链表,这个双向链表中每个结点的共同点是,他们的槽都在同一个QObject对象上,这个链表的头结点就是这个Qobject对象的sender。这两个链表会有交叉(共同结点),但他们有不同的链接指针,所以不是同一个链表。
知道了这些,再来理解connect和disconnect就容易了。Connect的时候,就是先new一个Connection对象出来,设置好这个连接的信息后,将它分别添加到上面提到的两个链表中;disconnect的时候,就从从这两个链表中将它移除,然后delete掉。而当一个QObject对象被销毁的时候,它的sender指针指向的那个双向链表中的所有连接都会被逐个移除!
*******************************************************
讨论一下另一个不相关的问题:
写到这里正好附加一段说明。不知道有没有朋友注意到,我们在Qt开发过程中经常用到的connect函数,它的返回类型也是Connection。但是,那个Connection是QMetaObject命名域中的Connection类,而不是我们上面一直讨论的QObjectPravite命名域中的那个。那QMetaObject:: Connection类中包含哪些信息呢?它跟QObjectPravite::Connection又有何关系?
下面看QMetaObject::Connection的定义。可以看出,QMetaObject::Connection的第一个成员d_ptr就是一个QObjectPravite::Connection指针,所以QMetaObject::Connection已经包含了QObjectPravite::Connection类中的所有特性。
class Q_CORE_EXPORT QMetaObject::Connection { void *d_ptr; //QObjectPrivate::Connection* explicit Connection(void *data) : d_ptr(data) { } friend class QObject; friend class QObjectPrivate; friend struct QMetaObject; public: ~Connection(); Connection(); Connection(const Connection &other); Connection &operator=(const Connection &other); #ifdef Q_QDOC operator bool() const; #else typedef void *Connection::*RestrictedBool; operator RestrictedBool() const { return d_ptr ? &Connection::d_ptr : 0; } #endif #ifdef Q_COMPILER_RVALUE_REFS inline Connection(Connection &&o) : d_ptr(o.d_ptr) { o.d_ptr = 0; } inline Connection &operator=(Connection &&other) { qSwap(d_ptr, other.d_ptr); return *this; } #endif };
- 关于Qt中信号和槽的Connection
- 关于Qt中自定义槽和信号的简单示例
- 关于Qt中自定义槽和信号的简单示例
- qt中信号和槽的总结
- QT中自定义的信号和槽
- QT中关于信号与槽机制的实现原理
- QT中关于信号与槽机制的实现原理
- QT中关于信号与槽机制的实现原理
- QT中关于信号与槽机制的实现原理
- QT中关于信号与槽机制的实现原理
- QT中关于信号与槽机制的实现原理
- QT的信号和信号槽
- 关于linux异步通知signal 和QT的信号槽
- 关于Qt中信号槽机制
- 关于Qt中信号槽机制
- QT的信号和槽
- Qt的信号和槽
- QT的信号和槽
- 自主防护的数据安全体系
- char控件
- android增量更新demo
- Ubuntu 下ftp服务器的安装配置
- Cocos2d-x笔记(3)
- 关于Qt中信号和槽的Connection
- 南阳理工OJ_题目710 外星人的供给站
- Cocos2d-x笔记(4)
- math.h 功能索引
- 小分队线下技术交流会火热来袭!
- OM问题集锦
- 自动选择SVG和VML的WEB页面
- 将二维码包装成成品
- hdu 2084 数塔