Qt源码分析3)QMetaObjectPrivate,QLineEditPrivate等分析

本文深入分析Qt库中QObject的QMetaObjectPrivate结构,探讨QMetaObject的invokeMethod方法及Widget的源码实现。着重讲解QObject作为基类在QT中的角色,以及如何理解Qt类中的Private嵌套结构,例如QMetaMethodPrivate和QLineEditPrivate。通过这些解析,帮助读者更好地理解Qt框架的内部工作原理。
摘要由CSDN通过智能技术生成

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);
  1. 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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值