• 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 orQApplication instance for processing and delivery. QAbstractEventDispatcher provides fine-grained control over event delivery.
     
    也就是说,使用QAbstractEvent,或者说使用EventLoop,需要有QCoreApplication或者QApplication的存在。
    对于GUI程序,这一点不是问题。问题在于对于很多consoleUI命令行程序,很多时候我们并不创建QCoreApplication或者QApplication对象。这样的场景下Eventloop自然无法正常使用。
    因此,如果是在命令行中调用一个用这种方式封装的同步函数,必须有一个QCoreApplicaion或者QApplication对象存在。
  • 相关阅读:
    XP和Scrum的比较
    让PowerDesigner支持SQLite 3.0[转]
    对于大型公司项目平台选择j2ee的几层认识(一)
    对于大型公司项目平台选择j2ee的几层认识(三)
    Alpha、Beta、RC、GA版本的区别
    如何在XElement中使用XPath
    对于大型公司项目平台选择j2ee的几层认识(四)
    Thread与BeginInvoke
    对于大型公司项目平台选择j2ee的几层认识(二)
    修复VS 2010的Help Library管理器
  • 原文地址:https://www.cnblogs.com/h2zZhou/p/9597199.html
Copyright © 2020-2023  润新知