QT Q_OBJECT 和 signals/slots

Q_OBJECT宏在QObject类中用于存储元信息,维护信号和槽的对应表。QMetaObject类提供了访问这些元信息的接口,包括动态转换和信号槽的调用。信号/槽通过索引调用,保证高效执行。当信号发射时,QMetaObject::activate被调用,Connection结构体存储了信号发射器和接收器的信息,管理信号和槽的连接。QThread作为QObject的子类,也支持信号/槽机制。
摘要由CSDN通过智能技术生成

Q_OBJECT宏展开

#define Q_OBJECT \
public: \
    QT_WARNING_PUSH \
    Q_OBJECT_NO_OVERRIDE_WARNING \
    static const QMetaObject staticMetaObject; \
    virtual const QMetaObject *metaObject() const; \
    virtual void *qt_metacast(const char *); \
    virtual int qt_metacall(QMetaObject::Call, int, void **); \
    QT_TR_FUNCTIONS \
private: \
    Q_OBJECT_NO_ATTRIBUTES_WARNING \
    Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
    QT_WARNING_POP \
    struct QPrivateSignal {}; \
    QT_ANNOTATE_CLASS(qt_qobject, "")
  • QMetaObject类的作用是为QObject子类存储所有的元信息;还维护类的信号和槽之间的对应表,以及任何连接的类的信号和槽对应表。每一个信号槽都被分配了一个唯一的索引:
  • metaObject()函数对于普通的Qt类返回&staticMetaObject;处理QML对象返回dynamicMetaObject
  • qt_metacast()函数使用类的名称进行动态转换。这个函数是必须的,因为Qt不依赖标准C++RTTI(运行时类型信息)来检索关于一个对象或一个类的元数据
  • qt_metacast()直接通过索引调用一个内部信号或槽。因为使用的是索引而不是指针,所以没有指针的指针解读,生成的switch case可以被编译器大量优化(编译器可以在很早的时候直接包含跳转指令到特定的情况,避免大量的分支评估)。因此,信号/槽机制的执行是相当快的

siganls/slots/emit

  • 定义

    #define slots
    #define signals public
    #define emit
    
  • 当一个信号关键词被发射,QMetaObject::activate()被调用并带有改变的值和信号索引

  • QObject::connect():创建一个新的Connection,在qobject_p.h定义

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 **prev;
    //...
};
  • Connection实例存储了一个指向信号发射器类(sender)、槽接收器类(receiver)的指针,及连接的信号槽关键字的索引。当一个信号被发射出去,每一个连接的槽都必须被调用。为了能做到这一点,每一个QObject为它每个信号都有一个Connection实例的链接列表,它的每个槽关键字也有同样的Connection链接列表
  • 这对链接列表允许Qt正确地走到每个依赖槽/信号对,以使用索引触发正确的函数。同理处理接收器的销毁。Qt走过双链接列表,将对象从它连接的地方删除
  • 这些机制发生在UI线程中。因为QThread类继承了QObject,任何QThread都可以使用信号/槽机制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值