深入理解QT的SIGNAL\SLOT机制(五):信号的发射过程
2017-12-20 11:40
771 查看
我们来看信号的发起过程,先来看一个宏定义:
废话不多说,来DEBUG:
![](http://img.blog.csdn.net/20171220110552198?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVsaXdlaXdlaWJh/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
我们在11行打断点F11进入:
居然直接调用了moc文件中的mysignal函数,现在是不是更清楚信号就是函数了啊?这里的this是MyWidget对象,staticMetaObject就是第二章提到的静态QMEtaObject,其余都是空。进入active函数之前回去先计算偏移量:
![](http://img.blog.csdn.net/20171220110942383?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVsaXdlaXdlaWJh/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
822~824行:将QMetaObject的所有父类偏移量加起来,目的是找到子类的第一个信号的偏移量(5.9.1中除了类名信息之外,只存储了信号和槽的信息)。现在进入active函数:
![](http://img.blog.csdn.net/20171220111247086?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVsaXdlaXdlaWJh/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
3636行:子类第一个信号的偏移量+当前偏移量,就是我们需要的mysignal信号的偏移量。
3637~3660行:进行安全检查,检查是否绑定信号和槽。
接着来看:
![](http://img.blog.csdn.net/20171220112602780?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVsaXdlaXdlaWJh/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
3694行:根据信号的signal_index下标查找到connectionList,这个connectionList存储的是所有绑定到该信号的槽函数信息;
![](http://img.blog.csdn.net/20171220112200276?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVsaXdlaXdlaWJh/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
3700~3705行:拿到列表的first和last,进行遍历。
3707~3709行:receiver是空,就意味着没有槽函数,continue;
3712~3721行:针对不同类型进行不同的处理;
我们的是在统一个线程中,调用3743行的switchSender函数,不同线程的是放到队列中去;
![](http://img.blog.csdn.net/20171220112246400?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVsaXdlaXdlaWJh/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
来看switchSender函数:
发现该函数基本是进行值拷贝,继续来看active函数:
3757~3766行:如果c->callFunction不为空,并且c->methodOffset在QMetaObject的methodOffset之内(保证调用的函数偏移量不超过QMetaObject的偏移量),就可以调用callFunction.
我们看到
和
实际上就是在调用callFunction,也就是moc_test.cpp中的qt_static_metacall函数。
调用完之后继续执行do{}while(),知道所有的槽被调用。
接下来按F11,进入callFunction
![](http://img.blog.csdn.net/20171220113756598?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVsaXdlaXdlaWJh/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
可以看到确实调用了moc_test.cpp中的static_metacall函数,
71行:格局传入的id调用对应的槽函数,所以myslot被调用。
OK,完结撒花!
如有问题欢迎指正
电子科技大学
胡力卫
15373632531@163.com
# define emit,这个宏定义将emit定义为空,也就是说你在emit mysignal()的时候,这行代码其实就是mysignal(),所以信号就是函数,只是换了个概念而已!
废话不多说,来DEBUG:
我们在11行打断点F11进入:
// SIGNAL 0 void MyWidget::mysignal() { QMetaObject::activate(this, &staticMetaObject, 0, nullptr); }
居然直接调用了moc文件中的mysignal函数,现在是不是更清楚信号就是函数了啊?这里的this是MyWidget对象,staticMetaObject就是第二章提到的静态QMEtaObject,其余都是空。进入active函数之前回去先计算偏移量:
822~824行:将QMetaObject的所有父类偏移量加起来,目的是找到子类的第一个信号的偏移量(5.9.1中除了类名信息之外,只存储了信号和槽的信息)。现在进入active函数:
3636行:子类第一个信号的偏移量+当前偏移量,就是我们需要的mysignal信号的偏移量。
3637~3660行:进行安全检查,检查是否绑定信号和槽。
接着来看:
3694行:根据信号的signal_index下标查找到connectionList,这个connectionList存储的是所有绑定到该信号的槽函数信息;
3700~3705行:拿到列表的first和last,进行遍历。
3707~3709行:receiver是空,就意味着没有槽函数,continue;
3712~3721行:针对不同类型进行不同的处理;
我们的是在统一个线程中,调用3743行的switchSender函数,不同线程的是放到队列中去;
来看switchSender函数:
inline void switchSender(QObject *receiver, QObject *sender, int signal_absolute_id) { this->receiver = receiver; currentSender.sender = sender; currentSender.signal = signal_absolute_id; currentSender.ref = 1; previousSender = QObjectPrivate::setCurrentSender(receiver, ¤tSender); switched = true; }
发现该函数基本是进行值拷贝,继续来看active函数:
3757~3766行:如果c->callFunction不为空,并且c->methodOffset在QMetaObject的methodOffset之内(保证调用的函数偏移量不超过QMetaObject的偏移量),就可以调用callFunction.
我们看到
const auto callFunction = c->callFunction;
和
callFunction(receiver, QMetaObject::InvokeMetaMethod, method_relative, argv ? argv : empty_argv);
实际上就是在调用callFunction,也就是moc_test.cpp中的qt_static_metacall函数。
调用完之后继续执行do{}while(),知道所有的槽被调用。
接下来按F11,进入callFunction
可以看到确实调用了moc_test.cpp中的static_metacall函数,
71行:格局传入的id调用对应的槽函数,所以myslot被调用。
OK,完结撒花!
如有问题欢迎指正
电子科技大学
胡力卫
15373632531@163.com
相关文章推荐
- 深入理解QT的SIGNAL\SLOT机制(二):QMetaObject相关知识
- 简单的2个实例,助你理解Qt的自定义Signal & Slot机制
- 信号(Signal)与槽(Slot)-Qt中的典型机制
- 信号(Signal)与槽(Slot)-Qt中的典型机制
- 深入理解Qt信号和槽机制、信号和槽中的Lambda表达式
- 信号(Signal)与槽(Slot)-Qt中的典型机制
- 信号(Signal)与槽(Slot)-Qt中的典型机制
- 深入理解QT的SIGNAL\SLOT机制(一):SIGNAL\SLOT如何使用
- Java实现Qt的SIGNAL-SLOT机制(保存到Map中,从而将它们关联起来,收到信号进行解析,最后反射调用)
- Qt的信号(signal)和槽(slot)机制(讲解很到位)
- Qt信号与槽机制(signal & slot)
- qt信号signal和槽slot机制
- 信号(Signal)与槽(Slot)-Qt中的典型机制
- Java实现Qt的SIGNAL-SLOT机制
- Qt深入理解信号与槽
- QT源码解析(二)深入剖析QT元对象系统和信号槽机制
- QT信号(SIGNAL)与槽(SLOT)
- 【深入QT】信号槽机制浅析
- Qt深入理解信号与槽
- 使用QT中的Signal&Slot机制进行传值