分享

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

 quasiceo 2013-03-13

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

分类: QT

 

版权声明

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

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

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

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

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

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

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

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

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

QT源码解析(九)解析QDateTime 

 

 

 

QT源码解析(三)深入剖析QT元对象系统和信号槽机制(续)文章中遗留了一个问题,就是当signal和slot的连接为Qt::QueuedConnection,这时候这个连接是怎么分发处理的。下面就结合一下Qt的源

代码来分析一下。

  1. if ((c->connectionType == Qt::AutoConnection  
  2.      && (currentThreadData != sender->d_func()->threadData  
  3.          || receiver->d_func()->threadData != sender->d_func()->threadData))  
  4.     || (c->connectionType == Qt::QueuedConnection)) {  
  5.     queued_activate(sender, signal, *c, argv);  
  6.     continue;  
  7. else if (c->connectionType == Qt::BlockingQueuedConnection) {  
  8.     blocking_activate(sender, signal, *c, argv);  
  9.     continue;  
  10. }  

这 段代码的意思是:当前connectionType为Qt::AutoConnection并且,signal和slot不在一个线程或者是signal 和不再当前线程中;或者是c->connectionType为 Qt::QueuedConnection这时候调用函数
queued_activate,如果c->connectionType 为Qt::BlockingQueuedConnection则调用函数blocking_activate
我们当queued_activate和blocking_activate一样就可以了。


queued_activate函数很简单,就是对参数转换一下,然后调用   
QCoreApplication::postEvent(c.receiver, new QMetaCallEvent(c.method,sender,signal,nargs,types,args,semaphore));
注意: postEvent第二个参数是QMetaCallEvent。这样这个signal-slot的connection就发送到receiver的消息队列中去了。
接下来消息队列如何处理QMetaCallEvent,请参考 QT源码解析(四)剖析Qt的事件机制原理


后记:通过这种方法Qt实现了跨线程的signal-slot传递,并且这种signal-slot机制的传递是利用消息队列,所以说是线程安全的。

 

 

 

 

 

查看评论
3楼 tingsking18 2010-02-01 19:58发表 [回复]
对。仔细看一下,不是很难理解的。
2楼 chinese_zmm 2010-02-01 19:03发表 [回复]
谢谢回复,我的理解是在第三篇的例子中,receiver和sender在不同的线程中,所以没有进入queued_activate或者blocking_activate方法,直接执行了,不知道对不对?
1楼 chinese_zmm 2010-01-29 08:38发表 [回复]
看 了前辈这一系列的文章,我想问一下,在这篇文章中提到的qt的signal-slot在不同的线程中会通过消息传递,那么我想问一下消息队列是不是可以独 立于GUI而存在的,因为在您的第三篇文章中的实例中qt的信号和槽就运行于多线程环境中,而且项目是一个控制台程序。
Re: tingsking18 2010-01-29 09:42发表 [回复]
消息队列不可以独立于GUI,
第三篇文章中提到的多线程的signal slot是不经过消息队列的。
你仔细看
if ((c->connectionType == Qt::AutoConnection
&& (currentThreadData != sender->d_func()->threadData
|| receiver->d_func()->threadData != sender->d_func()->threadData))
|| (c->connectionType == Qt::QueuedConnection)) {
queued_activate(sender, signal, *c, argv);
continue;
} else if (c->connectionType == Qt::BlockingQueuedConnection) {
blocking_activate(sender, signal, *c, argv);
continue;
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多