QT 异步函数转为同步函数的方法

在QT中,一般推荐使用异步函数。除了异步函数的非阻塞特性外,QT的Signal/Slot特性在异步函数中可以得到充分的发挥。因此,在QT中,很多API的设计都是使用非阻塞的异步函数作为API,然后执行结果使用Signal返回。用户执行API后使用slot函数接收反馈结果。

但是在很多场景下,我们的确可能需要同步函数。也就是说函数在返回执行结果之前必须阻塞,调用函数后必须得到相应的执行结果。这时候,对于大量使用signal/slot的QT程序来说,经常需要将一个异步函数转变为同步函数。具体的转换做法如下。

例如一个异步的login函数:

void login(const QString& username, const QString& password);
返回值使用signal通知:
OnLoginStatusChanged();
下面就是这个异步函数的同步版本:

int loginSync(const QString& username, const QString& password)
{
    int timeout = 30 * 1000;  //超时时间设置
    QTimer t ;
  QEventLoop q;
  t.setSingleShot(true);
  connect(&t, SIGNAL(timeout()), &q, SLOT(quit()));  //异步调用超时退出
  connect(this, SIGNAL(OnLoginStatusChanged()), &q, SLOT(quit()));  //异步调用完成退出
 
 
  Login(username, password);   //调用异步函数
  t.start(timeout); 
  q.exec();
   
  //以下可以根据异步函数的返回结果进行进一步操作并返回函数结果。
 
 
}


需要注意的是,EventLoop的ProcessEvent实际上封装的是 QAbstractEventDispatcher::processEvents。
QT帮助文件中有这样的描述:

An event dispatcher receives events from the window system and other sources. It then sends them to the 
 
  QCoreApplication  or QApplication  instance for processing and delivery. QAbstractEventDispatcher  provides fine-grained control over event delivery.

也就是说,使用QAbstractEvent,或者说使用EventLoop,需要有QCoreApplication或者QApplication的存在。
对于GUI程序,这一点不是问题。问题在于对于很多consoleUI命令行程序,很多时候我们并不创建QCoreApplication或者QApplication对象。这样的场景下Eventloop自然无法正常使用。
因此,如果是在命令行中调用一个用这种方式封装的同步函数,必须有一个QCoreApplicaion或者QApplication对象存在。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值