环境安装

默认安装好了VS2015 和QT

下载QT pdb和QT src压缩包(选择自己的版本,我是5.9.8)

qt下载网址

拷贝自己需要的文件,qt目录中D:\Qt\Qt5.9.8\5.9.8我是这个

并且把源码也拷贝进同一目录,当然其他的目录也行

设置VS选项

工具->选项->调试->符号

项目->xxxx属性->vc++目录(添加源码路径)

测试

对着qt的函数或者宏按F12

安装查看源码的软件(Source Insight)

这个工具可以很好的分析源码

分析QT信号槽

分析moc生成的文件

案例代码

#include class QtClass : public QObject{    Q_OBJECTpublic:    QtClass(QObject *parent);    ~QtClass();    void Test(){        emit Sig1(5);    }signals:    void Sig1(int nVal);     //void Sig2(bool b);    //void Sig3(bool b);    //void Sig4(bool b, int nVal);    private slots:    void Slot1(int nVal0){        qDebug() << nVal0;    }}

信号函数只有声明,没有实现?

emit Sig1(5);这句代码调用信号,但是我们没有实现信号这个函数呀。我们没有实现,那么是什么能够帮我们实现呢?当然是编译器。

调试信号函数

F11发现是有实现代码的吧

打开文件所在目录

查看moc文件夹,分析编译器都给我们生成了什么

定义了一个结构体

qt_meta_stringdata_QtClass_t

struct qt_meta_stringdata_QtClass_t {     QByteArrayData data[6];     char stringdata0[31];};

后面创建了一个结构体静态变量里面存放一些类、参数、函数名等信息。这个第一个参数应该是ID,字符串的开始位置,字符串size

QT_MOC_LITERAL(0, 0, 7), // "QtClass"

static const qt_meta_stringdata_QtClass_t qt_meta_stringdata_QtClass = {     {QT_MOC_LITERAL(0, 0, 7), // "QtClass" //类名QT_MOC_LITERAL(1, 8, 4), // "Sig1"      //信号名QT_MOC_LITERAL(2, 13, 0), // ""        QT_MOC_LITERAL(3, 14, 4), // "nVal" //参数名QT_MOC_LITERAL(4, 19, 5), // "Slot1" //槽函数名QT_MOC_LITERAL(5, 25, 5) // "nVal0"     //槽参数名     },    "QtClass\0Sig1\0\0nVal\0Slot1\0nVal0"};

qt_meta_data_QtClass : 存储类中函数相关的信息

static const uint qt_meta_data_QtClass[] = {  // content:       7,       // revision  //qt对应版本       0,       // classname        0,    0, // classinfo       2,   14, // methods   //2个函数 context长度14       0,    0, // properties       0,    0, // enums/sets       0,    0, // constructors       0,       // flags       1,       // signalCount //信号数量 // signals: name, argc, parameters, tag, flags       1,    1,   24,    2, 0x06 /* Public */,//name:对应qt_meta_stringdata_QtClass_t结构体的ID,是"Sig1"//argc:是参数个数//parameters:该函数的具体声明在在qt_meta_data_QtClass结构体的偏移 // slots: name, argc, parameters, tag, flags       4,    1,   27,    2, 0x08 /* Private */,//上面的parameters就是指向这里// 返回值   参数1... 这个结构的大小24 // signals: parameters    QMetaType::Void, QMetaType::Int,    3,27 // slots: parameters    QMetaType::Void, QMetaType::Int,    5,       0        // eod};

qt_static_metacall类的信号/槽函数调用的实现地址判断传进来的ID然后调用函数

void QtClass::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, {    if (_c == QMetaObject::InvokeMetaMethod) {        QtClass *_t = static_cast(_o);         Q_UNUSED(_t)         switch (_id) {        case 0: _t->Sig1((*reinterpret_cast< int(*)>(_a[1]))); break;         case 1: _t->Slot1((*reinterpret_cast< int(*)>(_a[1]))); break;         default: ;        }    } else if (_c == QMetaObject::IndexOfMethod) {         int *result = reinterpret_cast<int *>(_a[0]);        {            typedef void (QtClass::*_t)(int );             if (*reinterpret_cast<_t *>(_a[1]) == static_cast<_t>(&QtClass::                *result = 0;                 return;            }        }    }}

staticMetaObject : 类信息的总和

红色框是父类地址,蓝色是存储字符串的结构体的地址,黑色是存放信号槽函数信息的结构体,类的信号/槽函数调用的实现地址

metaObject:判断静态/动态调用

qt_metacast:返回类名称

+qt_metacall:函数调用

void** _a:数组指针, 每个指针指向一个函数的地址

_c:实现函数的类型

_id : 函数id, 判断是否实现 & 以何种方式实现该函数

信号函数的实现

void* _a[]是一个信号对应的槽函数的地址

一个信号可以对应多个槽,所有这里是void* _a[]数组

Q_OBJECT

从这里看是不是很明显的能看出,这里写了虚函数,然后生成moc文件帮我们实现

* qmake ignore 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 *, Q     QT_WARNING_POP \    struct QPrivateSignal {}; \    QT_ANNOTATE_CLASS(qt_qobject, "")

分析connect函数

检查函数

判断参数是否为NULL

给Sender赋值获取名字、对象、参数等

获取sender的Index,并且判断是否有效

接收方信息

判断信号槽是否被关联

判断接收方是否有效可以被关联

检查发送者和接收者参数是否一致

执行关联操作函数

进入实现函数

先是强转了sender 和receiver保存在两变量里面

检测版本

估计是为了防止多线程,给了锁

生成信号槽的对应关系Connection,并把Connection插入ConnectionList中

为对应的connect赋值

解锁,并且检查是否关联成功

分析activate函数

当我们发Sig1信号时调用的函数

红框计算父类的信号

前面做了一系列检查,是否还关联着

构造一个ConnectListRef的结构体,类似ConnectList引用

这里用上面的Index找到关联链表

遍历表找到对应得connect

调用链表得槽函数

大体图

end

qt中实现息屏开平mousepress_QT信号槽分析相关推荐

  1. qt中实现息屏开平mousepress_Qt实用技能5-掌握信号槽使用细节

    目录 (放个目录方便预览.这个目录是从博客复制过来的,点击会跳转到博客) 简介 信号与槽的声明 信号-槽的使用 信号的使用 槽函数的使用 信号-槽的"元调用" 信号和信号的参数 注 ...

  2. qt中实现息屏开平mousepress_Qt元对象(Meta-Object)系统与反射

    前言 给部门内部培训Qt相关的一些注意点用的,我提取出来放到自己的博客上了.欢迎各位大佬吐嘈 原文链接 Qt元对象(Meta-Object)系统与反射 - C++ Programer​www.cryf ...

  3. 【QT|趣谈】最详细的信号槽机制介绍!

    用最有趣的方式解释信号槽通讯机制 1 导语:信号槽的前世今生 2 QT的信号槽 2.1什么是信号槽? 2.2 用严谨的语言解释信号槽 3 信号槽实战 3.1 信号槽实例 4 信号槽plus 4.1 L ...

  4. Qt学习之路(4):初探信号槽

    看过了简单的Hello, world! 之后,下面来看看Qt最引以为豪的信号槽机制! 所谓信号槽,简单来说,就像是插销一样:一个插头和一个插座.怎么说呢?当某种事件发生之后,比如,点击了一下鼠标,或者 ...

  5. QT子线程与主线程的信号槽通信

    最近用QT做一个服务器,众所周知,QT的主线程必须保持畅通,才能刷新UI.所以,网络通信端采用新开线程的方式.在涉及到使用子线程更新Ui上的控件时遇到了点儿麻烦.网上提供了很多同一线程不同类间采用信号 ...

  6. Qt中绑定信号槽之后,信号槽无效

    下面程序编译没有错误,运行却未达到想要的效果,最后调试发现,是信号槽绑定后无效,即槽函数没有受到信号的触发.具体代码如下: main.cpp #include <QtCore> #incl ...

  7. 最新QT从入门到实战完整版(08.qt中的坐标系-09 信号和槽-点击按钮关闭窗口_)

    最新QT从入门到实战完整版(08.qt中的坐标系-09 信号和槽-点击按钮关闭窗口_) 一.08.qt中的坐标系 二,09 信号和槽-点击按钮关闭窗口_ 来自 一.08.qt中的坐标系 二,09 信号 ...

  8. Qt线程间信号槽传递自定义数据类型(qRegisterMetaType的使用)

    Qt线程间信号槽传递自定义数据类型(qRegisterMetaType的使用) #include <QMetaType> CFileDataModel::CFileDataModel(QO ...

  9. Qt中利用定时器QTimer实时显示当前日期和时间

    Qt中利用定时器QTimer实时显示当前日期和时间 时显示当前日期和时间.下面说明方法: 1. 在工程中声明一个全局QTimer对象 QTimer *timer; 2. 在构造函数中定义QTimer, ...

最新文章

  1. Android系统启动过程全解析
  2. yii2数组转为对象_好程序员Java学习路线分享java为什么不支持泛型数组
  3. @RestControllerAdvice与@ControllerAdvice的区别
  4. JavaScript学习(七十四)—递归函数
  5. iPhone位置跟踪器 For Windows版
  6. mysql sql slave skip_MySQL的一次错误处理 SQL_SLAVE_SKIP_COUNTER
  7. C# DevExpress ChartControl用法总结
  8. kux格式怎么转换成mp3_怎么把kux格式转换mp4、mp3?视频转换技巧介绍
  9. 常用的Unicode码表(汉字从A到Z、数字、英文)
  10. 奥西450的服务器系统,奥西TDS450
  11. 微信账户冻结怎么解除
  12. 安卓Web Service实现天气预报功能
  13. Rollup项目的SNARK景观
  14. 百度超级链联合超级账本:区块链技术如何提升金融行业互信与安全
  15. Porotech 展示突破性的 MicroLED 显示器
  16. WPF基础到企业应用系列8——依赖属性之“风云再起”
  17. 阿里云HaaS100物联网开发板学习笔记(一)硬件资源介绍
  18. 国产热门操作系统Deepin试用感受
  19. 【Mysql SQLZOO练习命令练习】
  20. SQL 删除某列中某个字符串

热门文章

  1. LiveVideoStackCon讲师热身分享 ( 十一 ) —— 短视频APP的架构设计
  2. 深入理解 Lua 虚拟机
  3. Python—进程、线程、协程
  4. 直播未来属于RTMP还是HTTP?
  5. 基于Win32Api创建窗口程序
  6. Intel Edision开发工具简介
  7. 如何在maven的setting.xml中指定jdk版本(详细步骤)
  8. Hadoop权威指南 _01前言感悟
  9. maven环境下,控制台中文乱码
  10. leetcode 492. 构造矩形(Java版,三种解法)