QT源码解析(二)深入剖析QT元对象系统和信号槽机制

版权声明

请尊重原创作品。转载请保持文章完整性,并以超链接形式注明原始作者“tingsking18”和主站点地址,方便其他朋友提问和指正。

 

 

QT源码解析(一) QT创建窗口程序、消息循环和WinMain函数

QT源码解析(二)深入剖析QT元对象系统和信号槽机制

QT源码解析(三)深入剖析QT元对象系统和信号槽机制(续)

QT源码解析(四)剖析Qt的事件机制原理

QT源码解析(五)QLibrary跨平台调用动态库的实现

QT源码解析(六)Qt信号槽机制与事件机制的联系

QT源码解析(七)Qt创建窗体的过程

QT源码解析(八)Qt是如何处理windows消息的

QT源码解析(九)解析QDateTime

 

       QT的信号和槽机制是用来在对象间通讯的方法,当一个特定事件发生的时候,signal会被 emit 出来,slot 调用是用来响应相应的 signal 的。简单点说就是如何在一个类的一个函数中触发另一个类的另一个函数调用,而且还要把相关的参数传递过去.好像这和回调函数也有点关系,但是消息机制可比回调函数有用多了,也复杂多了。

       下面的代码是我写的一个继承QLabel的类,是QLabel可以响应鼠标单击的消息。

这段代码很简单,讲述了QTsingalslot的使用。下面我们就深入QT的源码内部,来看一看QT是如何实现singalslots的。

#include “main.moc” 的意思就是使编译器找到mocQ_OBJECT处理后的标准C++文件。编译的时候我们需要首先在该目录中使用 qmake -project 生成一个 .pro 文件,该文件含有工程细节,然后使用 qmake 产生 Makefile,最后 nmake 就可以产生可执行文件了。我们看看在nmake之后除了生成目标代码和可执行文件之外,还有一个main.moc文件,这个文件是moc产生的一个中间文件。

       现在我们要看一下Q_OBJECT宏到底是什么?他与main.moc有什么关联呢?相信我介绍完了Q_OBJECT宏之后,再看main.moc就能明白其所有函数的含义了。我们先到objectdefs.h 文件中看一下Q_OBJECT宏的定义:

#define Q_OBJECT /

public: /

 Q_OBJECT_CHECK /

 static const QMetaObject staticMetaObject; /

 virtual const QMetaObject *metaObject() const; /

 virtual void *qt_metacast(const char *); /

 QT_TR_FUNCTIONS /

 virtual int qt_metacall(QMetaObject::Call, int, void **); /

private:

1首先调用了 Q_OBJECT_CHECK (插入了一个 qt_check_for_QOBJECT_macro template function

2  然后是全局常量 QMetaObject 对象,因此可以用 QClassname::staticMetaObject 直接访问,另外提供了两个接口函数 metaObject() 用于不同的 class 返回自己的 staticMetaObjectqt_metacast() 用于转换,我们在 moc 产生的文件里面可以找到这两个接口的实现:

const QMetaObject *ClickedLabel::metaObject() const

{

    return &staticMetaObject;

}

 

void *ClickedLabel::qt_metacast(const char *_clname)

{

    if (!_clname) return 0;

    if (!strcmp(_clname, qt_meta_stringdata_ClickedLabel))

        return static_cast<void*>(const_cast< ClickedLabel*>(this));

    return QLabel::qt_metacast(_clname);

}

3  QT_TR_FUNCTIONS是和i18n相关的,我们暂时不用去管它。

#  define QT_TR_FUNCTIONS /

    static inline QString tr(const char *s, const char *c = 0) /

        { return staticMetaObject.tr(s, c); }

4         最后是接口函数qt_metacall,他的作用是查表,调用函数

int ClickedLabel::qt_metacall(QMetaObject::Call _c, int _id, void **_a)

{

    _id = QLabel::qt_metacall(_c, _id, _a);

    if (_id < 0)

        return _id;

    if (_c == QMetaObject::InvokeMetaMethod) {

        switch (_id) {

  • 8
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值