Qt带返回值的信号发射方式(使用QMetaObject::invokeMethod)
一般来说,我们发出信号使用emit这个关键字来操作,但是会发现,emit并不算一个调用,所以它没有返回值。那么如果我们发出这个信号想获取一个返回值怎么办呢?
两个办法:1.通过出参形式返回,引用或者指针的方式带回;比如emit sig(int& i)或者emit sig(void* pointer),但是这个方法有一个弊端,稍后介绍第二种方式会提醒。
2.通过qt自带的invoke机制调用:参考文档对QMetaObject::invokeMethod的说明:Invokes the member (a signal or a slot name) on the object obj.也就是说回调是可以回调信号或者槽的。一般来说,我们使用invokeMethod是在子线程需要调度UI操作的时候(已经有很多文章详细说明了使用方式,不再赘述),因为UI操作只能在主线程中使用(否则会出现未定义错误),通过这种回调方式,让要操作的事件回到主线程时间片的时候再来执行。大部分情况下,我们把UI操作封装在一个槽里,用回调方式来调度。同样信号也可以用这种方式,但是有几点需要注意的是,1.调用回调的连接方式:如果信号和连接槽在一个线程内,那么必须用Qt::DirectConnection或者Qt::AutoConnection,这样的话,保证信号回调后,线程会等待信号连接槽执行完毕,才可能取到我们需要的返回值;如果使用了Qt::QueuedConnection,那么信号只是负责把事件交给事件队列,然后马上做出返回,这样,是否有返回值就无法确定了(这也就是第一个方法的弊端,因为信号发射是根据信号和槽各自的线程情况来选择的连接方式).如果信号和槽在两个线程中,那么首先肯定不能使用Qt::DirectConnection,除非你很清楚连接槽的动作是否保证了线程安全。但根据第一条的说明,也不能使用Qt::QueuedConnection。不过还好qt提供了一个额外的连接方式就是Qt::BlockingQueuedConnection,这个连接方式会阻塞住发射信号的线程一直等到队列连接槽返回后,才会恢复阻塞,这样就可以保证我们能拿到真正的返回值。(但是使用这种方式需要你清楚的知道,发射线程是否允许阻塞和连接槽是否对这个阻塞线程有什么特别的操作,一般来说,如果这个线程并不是由你自己控制的话,不要随便尝试去阻塞别人的线程,因为你并不清楚别人线程的执行逻辑)
调用方式大致代码如下bool bReturn; QMetaObject::invokeMethod(&object, "sig", Qt::DirectConnection/*Qt::QueuedConnection*/, Q_RETURN_ARG(bool, bReturn), Q_ARG(int, i));
Qt带返回值的信号发射方式(使用QMetaObject::invokeMethod)的更多相关文章
- Qt::带返回值的信号发射方式
一般来说,我们发出信号使用emit这个关键字来操作,但是会发现,emit并不算一个调用,所以它没有返回值.那么如果我们发出这个信号想获取一个返回值怎么办呢? 两个办法:1.通过出参形式返回,引用或者指 ...
- Qt信号槽的一些事 Qt::带返回值的信号发射方式
一般来说,我们发出信号使用emit这个关键字来操作,但是会发现,emit并不算一个调用,所以它没有返回值.那么如果我们发出这个信号想获取一个返回值怎么办呢? 两个办法:1.通过出参形式返回,引用或者指 ...
- 慕课网-Java入门第一季-7-3 Java 中无参带返回值方法的使用
来源:http://www.imooc.com/code/1579 如果方法不包含参数,但有返回值,我们称为无参带返回值的方法. 例如:下面的代码,定义了一个方法名为 calSum ,无参数,但返回值 ...
- Java 中带参带返回值方法的使用
如果方法既包含参数,又带有返回值,我们称为带参带返回值的方法. 例如:下面的代码,定义了一个 show 方法,带有一个参数 name ,方法执行后返回一个 String 类型的结果 调用带参带返回值的 ...
- Java 中无参带返回值方法的使用
如果方法不包含参数,但有返回值,我们称为无参带返回值的方法. 例如:下面的代码,定义了一个方法名为 calSum ,无参数,但返回值为 int 类型的方法,执行的操作为计算两数之和,并返回结果 在 c ...
- EF5中 执行 sql语句使用Database.ExecuteSqlCommand 返回影响的行数 ; EF5执行sql查询语句 Database.SqlQuery 带返回值
一: 执行sql语句,返回受影响的行数 在mysql里面,如果没有影响,那么返回行数为 -1 ,sqlserver 里面 还没有测试过 using (var ctx = new MyDbConte ...
- 测试 多线程 实现 callable 带返回值
package threadTest; import java.util.ArrayList; import java.util.Date; import java.util.concurrent.C ...
- Mysql带返回值与不带返回值的2种存储过程
过程1:带返回值: 1 drop procedure if exists proc_addNum; 2 create procedure proc_addNum (in x int,in y int, ...
- c++中带返回值函数没写return能通过编译但运行时会出现奇怪问题
c++中带返回值函数没写return能通过编译但运行时会出现奇怪问题 例如: string myFunc(){ theLogics(); } 发现调用: myFunc(); 崩溃. 但调用: cout ...
随机推荐
- 单片机成长之路(51基础篇) - 007 CH340CH341最全说明
比较全的CH340,CH341应用说明 CH340 以前用USB转串口时图方便一般也都是直接买现成的USB转串口模块,但是后面设计需要,不等不将CH340这个模块集成到电路板中,经过多次失败,终于得到 ...
- solr+zookeeper集群配置
将solr配置文件交给zookeeper进行管理 ./zkcli.sh -zkhost node01:2181,node02:2181,node03:2181 -cmd upconfig -confd ...
- vue 实站技巧总结
多个页面都使用的到方法,放在 vue.prototype上会很方便 刚接触 vue的时候做过一件傻事,因为封装了一个异步请求接口post,放在 post.js文件里面,然后在每个需要使用异步请求的页面 ...
- Redis 的事务到底是不是原子性的
ACID 中关于原子性的定义: 原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节.事务在执行过程中发生错误,会被恢复(Rollback)到事 ...
- Kafka Docker集群搭建
1. Zookeeper下载 http://apache.org/dist/zookeeper/ http://mirrors.hust.edu.cn/apache/zookeeper/zookeep ...
- AOSP中的HLS协议解析
[时间:2018-04] [状态:Open] [关键词:流媒体,stream,HLS, AOSP, 源码分析,HttpLiveSource, LiveSession,PlaylistFetcher] ...
- NetBeans使用Consolas中文乱码的解决
1.进入jdk安装目录下/jre/lib文件夹,找到fontconfig.properties.src,拷贝为 fontconfig.properties ,修改此文件. 找到: sequence.m ...
- Windows上SSH服务器的配置以及客户端的连接
1. ssh简介以及本例的应用场景 ① ssh的简介 SSH是一个用来替代TELNET.FTP以及R命令的工具包,主要是想解决口令在网上明文传输的问题.为了系统安全和用户自身的权 ...
- js 时间戳转时间工具类 js时间戳与时间互转
/** * 时间戳格式化函数 * @param {string} format 格式 * @param {int} timestamp 要格式化的时间 默认为当前时间 * @return {strin ...
- rabbitmq web管理
celery突然连接不上rabbitmq server,结果找半天发现是rabbitmq卡的不行... rabbitmq 设置web管理,添加用户 rabbitmqctl list_queues | ...