qt中实现息屏开平mousepress_QT信号槽分析
默认安装好了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信号槽分析相关推荐
- qt中实现息屏开平mousepress_Qt实用技能5-掌握信号槽使用细节
目录 (放个目录方便预览.这个目录是从博客复制过来的,点击会跳转到博客) 简介 信号与槽的声明 信号-槽的使用 信号的使用 槽函数的使用 信号-槽的"元调用" 信号和信号的参数 注 ...
- qt中实现息屏开平mousepress_Qt元对象(Meta-Object)系统与反射
前言 给部门内部培训Qt相关的一些注意点用的,我提取出来放到自己的博客上了.欢迎各位大佬吐嘈 原文链接 Qt元对象(Meta-Object)系统与反射 - C++ Programerwww.cryf ...
- 【QT|趣谈】最详细的信号槽机制介绍!
用最有趣的方式解释信号槽通讯机制 1 导语:信号槽的前世今生 2 QT的信号槽 2.1什么是信号槽? 2.2 用严谨的语言解释信号槽 3 信号槽实战 3.1 信号槽实例 4 信号槽plus 4.1 L ...
- Qt学习之路(4):初探信号槽
看过了简单的Hello, world! 之后,下面来看看Qt最引以为豪的信号槽机制! 所谓信号槽,简单来说,就像是插销一样:一个插头和一个插座.怎么说呢?当某种事件发生之后,比如,点击了一下鼠标,或者 ...
- QT子线程与主线程的信号槽通信
最近用QT做一个服务器,众所周知,QT的主线程必须保持畅通,才能刷新UI.所以,网络通信端采用新开线程的方式.在涉及到使用子线程更新Ui上的控件时遇到了点儿麻烦.网上提供了很多同一线程不同类间采用信号 ...
- Qt中绑定信号槽之后,信号槽无效
下面程序编译没有错误,运行却未达到想要的效果,最后调试发现,是信号槽绑定后无效,即槽函数没有受到信号的触发.具体代码如下: main.cpp #include <QtCore> #incl ...
- 最新QT从入门到实战完整版(08.qt中的坐标系-09 信号和槽-点击按钮关闭窗口_)
最新QT从入门到实战完整版(08.qt中的坐标系-09 信号和槽-点击按钮关闭窗口_) 一.08.qt中的坐标系 二,09 信号和槽-点击按钮关闭窗口_ 来自 一.08.qt中的坐标系 二,09 信号 ...
- Qt线程间信号槽传递自定义数据类型(qRegisterMetaType的使用)
Qt线程间信号槽传递自定义数据类型(qRegisterMetaType的使用) #include <QMetaType> CFileDataModel::CFileDataModel(QO ...
- Qt中利用定时器QTimer实时显示当前日期和时间
Qt中利用定时器QTimer实时显示当前日期和时间 时显示当前日期和时间.下面说明方法: 1. 在工程中声明一个全局QTimer对象 QTimer *timer; 2. 在构造函数中定义QTimer, ...
最新文章
- Android系统启动过程全解析
- yii2数组转为对象_好程序员Java学习路线分享java为什么不支持泛型数组
- @RestControllerAdvice与@ControllerAdvice的区别
- JavaScript学习(七十四)—递归函数
- iPhone位置跟踪器 For Windows版
- mysql sql slave skip_MySQL的一次错误处理 SQL_SLAVE_SKIP_COUNTER
- C# DevExpress ChartControl用法总结
- kux格式怎么转换成mp3_怎么把kux格式转换mp4、mp3?视频转换技巧介绍
- 常用的Unicode码表(汉字从A到Z、数字、英文)
- 奥西450的服务器系统,奥西TDS450
- 微信账户冻结怎么解除
- 安卓Web Service实现天气预报功能
- Rollup项目的SNARK景观
- 百度超级链联合超级账本:区块链技术如何提升金融行业互信与安全
- Porotech 展示突破性的 MicroLED 显示器
- WPF基础到企业应用系列8——依赖属性之“风云再起”
- 阿里云HaaS100物联网开发板学习笔记(一)硬件资源介绍
- 国产热门操作系统Deepin试用感受
- 【Mysql SQLZOO练习命令练习】
- SQL 删除某列中某个字符串