解析Qt元对象系统(五) Q_INVOKABLE与invokeMethod(automatic connection从Qt4.8开始的解释已经与之前不同,发送对象驻足于哪一个线程并不重要,起到决定作用的是接收者对象所驻足的线程以及发射信号(该信号与接受者连接)的线程是不是在同一个线程)good
概述
查看Qt源码可知,Q_INVOKABLE是个空宏,目的在于让moc识别。
使用Q_INVOKABLE来修饰成员函数,目的在于被修饰的成员函数能够被元对象系统所唤起。
Q_INVOKABLE与QMetaObject::invokeMethod均由元对象系统唤起。这一机制在Qt C++/QML混合编程,跨线程编程,Qt Service Framework 以及 Qt/ HTML5混合编程以及里广泛使用。
QMetaObject::invokeMethod的声明如下,还有几个inline重载:
static bool invokeMethod(QObject *obj, const char *member,
Qt::ConnectionType,
QGenericReturnArgument ret,
QGenericArgument val0 = QGenericArgument(Q_NULLPTR),
...... //后面还有9个参数
1
2
3
4
5
函数为静态函数,用法是尝试调用对象obj的方法member(注意member可以为信号或者是槽),如何member可以被调用,则返回真,否则返回假。QMetaObject::invokeMethod可以是异步调用,也可以是同步调用。这取决与它的连接方式Qt::ConnectionType type。如果type为Qt::DirectConnection,则为同步调用,若为Qt::QueuedConnection,则为异步调用。
调用机制
direct connection 是指:发起信号的线程会直接触发其所连接的槽;
queued connection 是指:一个事件被派发到接收者所在的线程中,在这里,事件循环会之后的某一时间将该事件拾起并引起槽的调用;
blocking queued connection 与queued connection的区别在于,发送者的线程会被阻塞,直至接收者所在线程的事件循环处理发送者发送(入栈)的事件,当连接信号的槽被触发后,阻塞被解除;
automatic connection (缺省默认参数) 是指: 如果接收者所依附的线程和当前线程是同一个线程,direct connection会被使用。否则使用queued connection。
从Qt4.8开始的解释已经与之前不同,发送对象驻足于哪一个线程并不重要,发送者对象本身在哪一个线程对与信号槽连接类型不起任何作用,起到决定作用的是接收者对象所驻足的线程以及发射信号(该信号与接受者连接)的线程是不是在同一个线程。
看源码,发现invokeMethod最后调用QMetaMethod::invoke,在这里检查连接类型:
// 处理自动连接的情况
QThread *currentThread = QThread::currentThread();
QThread *objectThread = object->thread();
if (connectionType == Qt::AutoConnection) {
connectionType = currentThread == objectThread
? Qt::DirectConnection
: Qt::QueuedConnection;
}
1
2
3
4
5
6
7
8
对直接连接,直接调 metacall,它进而去调用对象的qt_metacall:
if (connectionType == Qt::DirectConnection) {
return QMetaObject::metacall(object, QMetaObject::InvokeMetaMethod, methodIndex, param) < 0;
1
2
对于队列连接,实际用的是postEvent派发了一个 QMetaCallEvent事件,也就是异步调用,这才能实现跨线程发送事件:
if (connectionType == Qt::QueuedConnection)
{ . . . . . .
QCoreApplication::postEvent(object, new QMetaCallEvent(idx_offset, idx_relative, callFunction,
0, -1, nargs, types, args));
}
1
2
3
4
5
常用的形式
QMetaObject::invokeMethod(object, "methodName", Qt::QueuedConnection,
Q_ARG(type1, arg1),
Q_ARG(type2, arg2));
1
2
3
还有一种是没有第三个参数,也就是不指明信号与槽的连接方式。
请注意,因为上面所示的参数需要被在构建事件时进行硬拷贝,参数的自定义型别所对应的类需要提供一个共有的构造函数、析构函数以及拷贝构造函数。而且必须使用注册Qt型别系统所提供的qRegisterMetaType() 方法来注册这一自定义型别。
---------------------
作者:SilentAssassin
来源:CSDN
原文:https://blog.csdn.net/yao5hed/article/details/81142365?utm_source=copy
版权声明:本文为博主原创文章,转载请附上博文链接!
解析Qt元对象系统(五) Q_INVOKABLE与invokeMethod(automatic connection从Qt4.8开始的解释已经与之前不同,发送对象驻足于哪一个线程并不重要,起到决定作用的是接收者对象所驻足的线程以及发射信号(该信号与接受者连接)的线程是不是在同一个线程)good的更多相关文章
- 解析Qt元对象系统(四) 属性系统(确实比较方便)
官方解释 我们在Qt源码中可以看到一个QObject的子类经常会用到一些Q_开头的宏,例如QMainWindow类开始部分代码是这样的: Q_PROPERTY(QSize iconSize READ ...
- 深入了解Qt(二)之元对象系统(Meta-Object System)
深入了解Qt主要内容来源于Inside Qt系列,本文做了部分删改,以便于理解.在此向原作者表示感谢! 在Qt Meta Object System-元对象系统这篇文章中,从底层实现的源码剖析了元对象 ...
- Qt元对象(Meta-Object)系统与反射
反射 -在计算机科学中,反射是指计算机程序在运行时(Run time)可以访问.检测和修改它本身状态或行为的一种能力.[1]用比喻来说,反射就是程序在运行的时候能够“观察”并且修改自己的行为. 要注意 ...
- QtCore是Qt的精髓(包括五大模块:元对象系统,属性系统,对象模型,对象树,信号槽)
作者:小豆君的干货铺链接:https://www.zhihu.com/question/27040542/answer/218384474来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业 ...
- Qt元对象系统简介
在Qt中提供了c++的扩展,提供了一种元对象系统的机制,(meta-object-system)的机制.其中包含了信号与槽的内部机制,能够访问到QObject子类的元对象信息的功能. Q_OBJECT ...
- Qt 元对象系统(Meta-Object System)
(转自:http://blog.csdn.net/aladdina/article/details/5496891) Qt的元对象系统基于如下三件事情: 类:QObject,为所有需要利用原对象系统的 ...
- Qt笔记——元对象系统
Qt元对象系统提供了对象间的通信机制:信号和槽.以及执行类形信息和动态属性系统的支持.是标注C++的一个扩展,它使得Qt可以更好的实现GUI图形用户界面编程.Qt的元对象系统不支持C++模板.虽然模板 ...
- Qt对象模型之二:对象树与元对象系统
一.对象树的概念 Qt中使用对象树(object tree)来组织和管理所有的QObject类及其子类的对象.当创建一个QObject时,如果使用了其他的对象作为其父对象(parent),那么这个 Q ...
- Qt 元对象系统(Meta-Object System)(不管是否使用信号槽,都推荐使用)
Qt 元对象系统(Meta-Object System) Qt的元对象系统基于如下三件事情: 类:QObject,为所有需要利用原对象系统的对象提供了一个基类. 宏:Q_OBJECT,通常可以声明在类 ...
随机推荐
- CSS3悬浮动画效果
利用CSS3的伪类元素hover以及transform,transition等动画属性,可以做出一些炫酷的动画效果.下面将一些项目中使用到的示例发布出来,供大家一起学习研究.演示地址:runjs. 浏 ...
- React Component 生命周期
一般而言 Component 有以下三种生命周期的状态: Mounting:已插入真实的 DOM Updating:正在被重新渲染 Unmounting:已移出真实的 DOM 针对 Component ...
- JavaScript定时器及其他
By Abyssly Jun 20 2014 Updated:Jun 20 2014 平时工作中不可避免地要嵌套网页,对JavaScript的深入了解还是很有必要滴.而JavaScript中一个容易让 ...
- CAD设置当前显示的光标(com接口VB语言)
主要用到函数说明: MxDrawXCustomFunction::Mx_SetCursor 设置当前显示的光标,光标可以从cur文件加载,详细说明如下: 参数 说明 CString sCursorFi ...
- openstack——nova计算服务
一.nova介绍 Nova 是 OpenStack 最核心的服务,负责维护和管理云环境的计算资源.OpenStack 作为 IaaS 的云操作系统,虚拟机生命周期管理也就是 ...
- 1 WebService 常见问题
<binding name="> <readerQuotas maxStringContentLength=" /> </binding> &l ...
- 阅读《JavaScript设计模式》第三章心得
简单工厂模式 1.通过类实例化对象创建 传统的用面向对象方法去创建很多类去实现某些功能不妥当,这样不仅占用的很多类名称,而且别人使用这些方法的同时要记住每个类的名字,所以这样不适合团队开发,所以我们可 ...
- hdu2005 第几天?【C++】
第几天? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu_2046_骨牌铺方格_201311251403
骨牌铺方格 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...
- [bzoj2783][JLOI2012]树_树的遍历
树 bzoj2783 JLOI2012 题目大意:给定一棵n个点的树.求满足条件的路径条数.说一个路径是满足条件的,当且仅当这条路径上每个节点深度依次递增且点权和为S. 注释:$1\le n\le 1 ...