1.温故知新:QObject 里面有个信号槽的 QMetaObject是个结构体外面在上一章总结过的,可以回顾看一下,这个结构体里面有个 class Connection 类和一些其他方法
static QMetaObject::Connection connect(const QObject *sender, const char *signal,
const QObject *receiver, const char *member, Qt::ConnectionType = Qt::AutoConnection);
- QMetaObjectPrivate 结构定义 ,QMetaObject::invokeMethod 方法源码 ,Widget 定义 源码 。特别提示:QObject 几乎是所有QT中的类的基类,因此QT中每个继承于Qobject的类都有这个指针,指向一个动态分配的QObjectData对象。QObjectPrivate 是QObjectData的子类,这样就合情合理了,各位可以从这个举例去解读Qt的所有这类嵌套型的源码,不管是QMetaObjectPrivate ,还是QLineEditPrivate 都可以这么去理解 。
///QObject 几乎是所有QT中的类的基类,因此QT中每个继承于Qobject的类都有这个指针,指向一个动态分配的QObjectData对象。
class Q_CORE_EXPORT QObjectData {
public:
virtual ~QObjectData() = 0;
QObject *q_ptr; 对象this指针
QObject *parent; 父对象指针
QObjectList children; typedef QList<QObject*> QObjectList; 这个是对象的子对象链表,区别于父类和子类
uint isWidget : 1; 是否是Wideget类型
uint blockSig : 1; 是否处于信号阻塞
uint wasDeleted : 1; 防止多次delete对象
uint isDeletingChildren : 1; 是否在delete子对象
uint sendChildEvents : 1; 是否向父对象报告对象插入和删除事件 应该为true
uint receiveChildEvents : 1; 是否接收子对象的事件消息 应该为ture
uint isWindow : 1; //for QWindow
uint unused : 25;
int postedEvents;
QDynamicMetaObjectData *metaObject;
QMetaObject *dynamicMetaObject() const;
};
///QObjectPrivate 是QObjectData的子类,这样就合情合理了。 事实上这个类是如此的重要,也是信息量很大的一个结构
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
{
Q_DECLARE_PUBLIC(QObject)
public:
struct ExtraData
{
ExtraData() {
}
#ifndef QT_NO_USERDATA
QVector<QObjectUserData *> userData;
#endif
QList<QByteArray> propertyNames;
QVector<QVariant> propertyValues;
QVector<int> runningTimers;
QList<QPointer<QObject> > eventFilters;
QString objectName;
}; //一些结构分别用来存放对象所属类的 property 运行时间等信息
typedef void (*StaticMetaCallFunction)(QObject *, QMetaObject::Call, int, void **);
struct Connection //重要的结构 保存每个信号和槽的连接
{
QObject *sender; 发送对象的指针
QObject *receiver; 接受对象的指针
union {
StaticMetaCallFunction callFunction; 接受对象的qt_static_metacall函数的指针
QtPrivate::QSlotObjectBase *slotObj;
};
// The next pointer for the singly-linked ConnectionList
Connection *nextConnectionList;
//senders linked list
Connection *next;
Connection **prev;
QAtomicPointer<const int> argumentTypes; 参数值数组指针
QAtomicInt ref_;
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;
Connection() : nextConnectionList(0), ref_(2), ownArgumentTypes(true) {
//ref_ is 2 for the use in the internal lists, and for the use in QMetaObject::Connection
}
~Connection();
int method() const {
Q_ASSERT(!isSlotObject); return method_offset + method_relative; }
void ref() {
ref_.ref(); }
void deref() {
if (!ref_.deref()) {
Q_ASSERT(!receiver);
delete this;
}
}
};
// ConnectionList is a singly-linked list 信号对应的槽链表,每一个信号对应一个该结构,每一个连接保存在一个connection
struct ConnectionList {
ConnectionList() : first(0), last(0) {
}
Connection *first;
Connection *last;
};
struct Sender
{
QObject *sender;
int signal;
int ref;
};
QObjectPrivate(int version = QObjectPrivateVersion);
virtual ~QObjectPrivate();
void deleteChildren();
void setParent_helper(QObject *);
void moveToThread_helper();
void setThreadData_helper(QThreadData *currentData, QThreadData *targetData);
void _q_reregisterTimers(void *pointer);
bool isSender(const QObject *receiver, const char *signal)