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 ...
随机推荐
- Atitit 烈火计划进展报告 r61
Atitit 烈火计划进展报告 r61 1. 烈火计划主要包括几个东西 1 1.1. 2014.12 邮箱编码读取 1 1.2. 2017.1 垂直领域图片下载器 草料图片下载器 1 1.3. q ...
- 【iCore1S 双核心板_ARM】例程二十:UART_IAP_ARM实验——更新升级STM32
实验现象及操作说明: 1.本例程共有两个代码包,APP和IAP,IAP程序功能实现将APP程序升级至STM32中. 2.直接上电或烧写程序将执行升级的APP应用程序. BIN升级文件产生方法: 1.编 ...
- Windows下pip安装及更新出现“UnicodeEncodeError: 'ascii' codec can't encode character u'\u258c' in position 8: ordinal not in range(128)”问题解决办法
Windows下pip安装及更新出现“UnicodeEncodeError: 'ascii' codec can't encode character u'\u258c' in position 8: ...
- javaEE中config.properties文件乱码解决办法
http://jingyan.baidu.com/article/ed2a5d1f3381d709f6be17f8.html ————————————————————————————————————— ...
- ATR的计算
TR=∣最高价-最低价∣和∣最高价-昨收∣和∣昨收-最低价∣的最大值 TR = max(high-low, abs(last-high), abs(last-low)) ATR = MA(TR, N) ...
- COUNT分组条件去重的sql统计语句示例(mysql)
常规情况下的sql分组统计为: ) from 表 where 条件 group by 字段; 但是有时往往需要添加不同的条件已经去重的统计以上语句就不能满足需求. 解决方案为: 1.添加条件的统计方案 ...
- TensorFlow at Google I/O 2018
2018 google I/O 上关于TF新功能以及TF技术生态方面的一些总结,更具体的内容可以去看2018 tfdev summit,这里面的内容会更加详细丰富.总的来说TensorFlow在庞大的 ...
- 一个有界任务队列的thradpoolexcutor, 直接捕获错误日志
基于官方的需要改版 1.改为有界,官方是吧所有任务添加到线程池的queue队列中,这样内存会变大,也不符合分布式的逻辑(会把中间件的所有任务一次性取完,放到本地的queue队列中,导致分布式变差) 2 ...
- C# SQLite数据库
在客户端配置文件<configuration>节点下,添加: <connectionStrings> <add name="localdb" conn ...
- Python的循环导入问题
循环导入的最好的解决方法是从架构上优化,即调整模块和模块成员变量的设计.一个好的原则是:可导出的成员变量,都不应该依赖于导入进来的成员变量. 但是在业务开发的过程中,总会遇到通过架构层面解决不了的导入 ...