QT异步信号槽函数转换为同步函数使用的一点经验
QT的信号槽机制
(关于这个机制褒贬不一,我们此处不做该机制的讨论。)
class Demo{ Q_OBJECT signals: void doSomethingFinished(QVariantList value,bool status); void errorOccurred(QVariant error); public slots: bool doSomething(); }
在使用Demo类的时候,调用函数 “doSomething()”,函数的当前返回值是告诉调用者,本次调用成功。但函数的功能完成之后的返回值由一个信号函数返回。
此机制其中一个优势是,可以异步调用刷新界面的更新,而不受同步调用的影响。
如何将QT的信号槽机制,转换成同步函数
异步函数的返回方式:
- 返回结果,触发了功能函数调用对应的信号返回。
- 返回错误,触发本类的全局或本功能函数专用的错误处理信号,返回错误。
- 返回超时,在限定时间内,功能函数未成功返回。
信号槽转同步函数的实现方式:
类结构:
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()进行处理,代码中我省掉了。
一个优化点
在我的实际操作中,使用了错误队列的处理方式来处理错误的返回。

浙公网安备 33010602011771号