QObject源码分析
2016-05-22 10:08
471 查看
/** *QObject.h * QObjectData存放着当前对象,父对象,子对象链表,元对象,元对象数据,以及一些标志位 */ class Q_CORE_EXPORT QObjectData { public: virtual ~QObjectData() = 0; QObject *q_ptr; /*QObject指针*/ QObject *parent; /*父对象指针*/ QObjectList children; /*子对象链表*/ uint isWidget : 1; /*是否为Widget,为1位,0和1*/ uint blockSig : 1; /*是否信号阻塞,为1位,0和1*/ uint wasDeleted : 1; /*是否已经删除,为1位,0和1*/ uint isDeletingChildren : 1; /*是否子对象链表删除,为1位,0和1*/ uint sendChildEvents : 1; /*发送子对象事件,为1位,0和1*/ uint receiveChildEvents : 1; /*接收子对象事件,为1位,0和1*/ uint isWindow : 1; //for QWindow /*是否为Window,为1位,0和1*/ uint unused : 25; /*未使用*/ int postedEvents; /*发布事件*/ QDynamicMetaObjectData *metaObject; /*动态元对象数据*/ QMetaObject *dynamicMetaObject() const; //assert dynamic /*元对象*/ }; /** *QObject_p.h *ExtraData结构存放着用户数据,属性名,属性值,定时器运行时间,事件过滤,对象名 *QObjectPrivate存放着QObjectConnectionListVector,向量中存放着链表,链表中存放着信号与槽 *也存放ExtraData,QThreadData,QObjectConnectionListVector */ 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; /*属性名*/ QList<QVariant> propertyValues; /*属性值*/ QVector<int> runningTimers; /*定时器运行时间*/ QList<QPointer<QObject> > eventFilters; /*事件过滤链表*/ QString objectName; /*对象名*/ }; typedef void (*StaticMetaCallFunction)(QObject *, QMetaObject::Call, int, void **); /*信号槽*/ struct Connection { QObject *sender; /*发送者*/ QObject *receiver; /*接收者*/ union { StaticMetaCallFunction callFunction; QtPrivate::QSlotObjectBase *slotObj; }; // The next pointer for the singly-linked ConnectionList Connection *nextConnectionList; /*下一个链表指针*/ //senders linked list Connection *next; /*下一个Connection对象指针*/ Connection **prev; /*上一个Connection对象双重指针*/ 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) const; QObjectList receiverList(const char *signal) const; QObjectList senderList() const; void addConnection(int signal, Connection *c); void cleanConnectionLists(); static inline Sender *setCurrentSender(QObject *receiver, Sender *sender); static inline void resetCurrentSender(QObject *receiver, Sender *currentSender, Sender *previousSender); static QObjectPrivate *get(QObject *o) { return o->d_func(); } int signalIndex(const char *signalName, const QMetaObject **meta = 0) const; inline bool isSignalConnected(uint signalIdx) const; // To allow abitrary objects to call connectNotify()/disconnectNotify() without making // the API public in QObject. This is used by QQmlNotifierEndpoint. inline void connectNotify(const QMetaMethod &signal); inline void disconnectNotify(const QMetaMethod &signal); template <typename Func1, typename Func2> static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot, Qt::ConnectionType type = Qt::AutoConnection); template <typename Func1, typename Func2> static inline bool disconnect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const typename QtPrivate::FunctionPointer<Func2>::Object *receiverPrivate, Func2 slot); static QMetaObject::Connection connectImpl(const QObject *sender, int signal_index, const QObject *receiver, void **slot, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type, const int *types, const QMetaObject *senderMetaObject); static QMetaObject::Connection connect(const QObject *sender, int signal_index, QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type); static bool disconnect(const QObject *sender, int signal_index, void **slot); public: ExtraData *extraData; // extra data set by the user QThreadData *threadData; // id of the thread that owns the object QObjectConnectionListVector *connectionLists; Connection *senders; // linked list of connections connected to this object Sender *currentSender; // object currently activating the object mutable quint32 connectedSignals[2]; union { QObject *currentChildBeingDeleted; QAbstractDeclarativeData *declarativeData; //extra data used by the declarative module }; // these objects are all used to indicate that a QObject was deleted // plus QPointer, which keeps a separate list QAtomicPointer<QtSharedPointer::ExternalRefCountData> sharedRefcount; }; /** *QObect.cpp *用向量保存着ConnectionList */ 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); } }; /** *QObject.cpp */ class Q_CORE_EXPORT QObject { Q_DECLARE_PRIVATE(QObject) /*得到QObjectData指针*/ /* Q_DECLARE_PRIVATE宏定义为: #define Q_DECLARE_PRIVATE(Class) \ inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr)); } \ inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr)); } \ friend class Class##Private; */ /*构造函数实例化QObjectPrivate对象并初始化*/ QObject::QObject(QObject *parent) : d_ptr(new QObjectPrivate) { Q_D(QObject); d_ptr->q_ptr = this; /*QObjectData*/ d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current(); /*QObjectPrivate*/ d->threadData->ref(); if (parent) { QT_TRY { if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData)) parent = 0; setParent(parent); } QT_CATCH(...) { d->threadData->deref(); QT_RETHROW; } } qt_addObject(this); if (Q_UNLIKELY(qtHookData[QHooks::AddQObject])) reinterpret_cast<QHooks::AddQObjectCallback>(qtHookData[QHooks::AddQObject])(this); } };
相关文章推荐
- Programming Scala第4章demo03 单例对象object
- javascript之object
- Objective-C ---点语法 (梳理整理)
- Objective-C ---代理和协议 (梳理整理)
- ObjectC Hook函数的实现与实战
- NSObject的方法说明
- 讲的很详细的一篇关于object equals() & hashCode() 的文章
- 使用cx_freeze工具打包时提示 AttributeError 'module' object has no attribute '_fix_up_module':
- Object Following for UAV(无人机物体跟随)
- iOS多线程之NSThread、NSOperationQueue、NSObject和GCD的区别
- Volley(2)—JsonObjectRequest和ImageRequest
- spring的 object is not an instance of declaring class
- 不管在不在arc下,object对象都有强引用、弱引用之分
- Xcode:duplicate declaration of method 'XXX'
- 重写Object类中的equals方法
- Programming with Objective-C(七)
- Objective-C Coding Style Guidelines
- scala学习13之与trait同名的object对象
- objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects
- SpringMVC数据格式转换报错:rejected value [065966] error in object 'command' on field 'imgNumber'