QT异步信号槽函数转换为同步函数使用的一点经验

QT的信号槽机制

(关于这个机制褒贬不一,我们此处不做该机制的讨论。)

class Demo{

Q_OBJECT
signals:

  void doSomethingFinished(QVariantList value,bool status);

  void errorOccurred(QVariant error);

public slots:

  bool doSomething();

}

在使用Demo类的时候,调用函数 “doSomething()”,函数的当前返回值是告诉调用者,本次调用成功。但函数的功能完成之后的返回值由一个信号函数返回。

此机制其中一个优势是,可以异步调用刷新界面的更新,而不受同步调用的影响。

如何将QT的信号槽机制,转换成同步函数

异步函数的返回方式:

  1. 返回结果,触发了功能函数调用对应的信号返回。
  2. 返回错误,触发本类的全局或本功能函数专用的错误处理信号,返回错误。
  3. 返回超时,在限定时间内,功能函数未成功返回。

信号槽转同步函数的实现方式:

类结构:

class SyncDemo{

public:

  SyncDemo();

signals:

  void  dealDoSomethingFinishedResult();

  void  errorOccurred();

public slots:

  QVariantList  syncDoSomething();

  void onSyncDoSomething(QVariantList value,bool status);

private:

  bool mDoSomethingStatus;

  QVariantList mDoSomethingResult; 

  Demo* mDemoClass;

  int mRequestTime;//ms

}

 

调用实现:

SyncDemo(){

  mDemoClass = new Demo();

  connect(mDemoClass ,&Demo::doSomethingFinished,this,&SyncDemo::onSyncDoSomething);

}

QVariantList  syncDoSomething(){

  //状态还原

  mDoSomethingStatus = false;

  mDoSomethingResult.clear();

  //同步部分

  QEventLoop syncLoop;

  connect(this,&SyncDemo::dealDoSomethingFinishedResult,&syncLoop,&QEventLoop ::quit);

  connect(mDemoClass ,&Demo::errorOccurred,&syncLoop,&QEventLoop::quit);

  QTimer timer;

  timer.setSingleShot(true);

  connect(&timer,&QTimer::timeout,&syncLoop,&QEventLoop::quit);

  timer.start(mRequestTime);

  mDemoClass->doSomething();

  syncLoop.exec();

  timer.stop();   //为什么此处多余一句stop?

  if(mDoSomethingStatus){

    return mDoSomethingResult;

  }

  else{

    return QVariantList();

  } 

}

void onSyncDoSomething(QVariantList value,bool status){

  mDoSomethingResult = value;

  mDoSomethingStatus = status;

  emit dealDoSomethingFinishedResult();

}

为什么要加一句stop?

因为QTimer是我们外部加入的,需要自己处理。不然会出现,代码执行时间较长时,quit()会在timer超时之后再被触发一次。

错误处理errorOccurred()

应该按照syncDoSomething()进行处理,代码中我省掉了。

一个优化点

在我的实际操作中,使用了错误队列的处理方式来处理错误的返回。

 

posted @ 2020-02-27 21:15  而立而励  阅读(1025)  评论(0)    收藏  举报