[英]Blocked waiting for a asynchronous Qt signal
我知道,那里有一些类似的问题,但我找不到能帮助我的具体答案。 所以这是我的问题:
我在一个应用程序上工作,在启动时执行一些gui-initialisations。 我要做的一件事就是打电话
NetworkConfigurationManager::updateConfigurations ()
这是一个异步调用,它在完成时发出updateCompleted()
信号。 问题是,我的所有其他gui-initialisations必须等到updateConfigurations()
完成。
所以我能做的就是这样:
MyApp::MyApp(QWidget *parent) : ....
{
doSomeInits();
//Now connect the signal we have to wait for
connect(configManager, SIGNAL(updateCompleted()), this, SLOT(networkConfigurationUpdated()));
configManager->updateConfigurations(); //call the async function
}
void MyApp::networkConfigurationUpdated()
{
doSomething();
doRemainingInitsThatHadToWaitForConfigMgr();
}
拆分初始化对我来说似乎不是一个好方法。 我认为它使代码更难阅读 - 内容应该保持在一起。 另一件事是:因为updateConfiguration()
是异步的 ,所以用户将能够使用GUI,它还没有给他任何信息,因为我们正在等待updateCompleted()
。
那么在应用程序继续之前有没有办法等待updateCompleted()
信号?
喜欢:
MyApp::MyApp(QWidget *parent) : ....
{
doSomeInits();
//Now connect the signal we have to wait for
connect(configManager, SIGNAL(updateCompleted()), this, SLOT(doSomething()));
???? //wait until doSomething() is done.
doRemainingInitsThatHadToWaitForConfigMgr();
}
在某些API中,存在异步函数的阻塞替代方案,但在这种情况下不是。
我感谢任何帮助。 谢谢!
这样做的方法是使用嵌套的事件循环。 您只需创建自己的QEventLoop,将要等待的任何信号连接到循环的quit()
槽,然后exec()
循环。 这样,一旦调用了信号,它就会触发QEventLoop的quit()
槽,从而退出循环的exec()
。
MyApp::MyApp(QWidget *parent) : ....
{
doSomeInits();
{
QEventLoop loop;
loop.connect(configManager, SIGNAL(updateCompleted()), SLOT(quit()));
configManager->updateConfigurations();
loop.exec();
}
doReaminingInitsThatHadToWaitForConfigMgr();
}
根据chalup的回答 ,如果你要等待用户明显的时间,你可能想要显示一个进度条 (或者可能是一个闪屏 )。
MyApp::MyApp(QWidget *parent) : ....
{
doSomeInits();
{
QSpashScreen splash;
splash.connect(configManager, SIGNAL(updateCompleted()), SLOT(close()));
configManager->updateConfigurations();
splash.exec();
}
doReaminingInitsThatHadToWaitForConfigMgr();
}
另一种解决方案可能是使用QSignalSpy :: wait() 。 这个功能在Qt 5中引入,完全符合你的要求。
我在该类中看到的唯一问题是它在QtTest模块中提供。 在我的情况下,我发现它在测试代码时非常有用,但它可能不是生产代码的最佳解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.