阻塞等待异步Qt信号

cyp*_*ous 22 c++ qt qt4

我知道,那里有一些类似的问题,但我找不到能帮助我的具体答案.所以这是我的问题:

我在一个应用程序上工作,在启动时执行一些gui-initialisations.我要做的一件事就是打电话

NetworkConfigurationManager::updateConfigurations ()
Run Code Online (Sandbox Code Playgroud)

这是一个异步调用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();
}
Run Code Online (Sandbox Code Playgroud)

拆分初始化对我来说似乎不是一个好方法.我认为它使代码更难阅读 - 内容应该保持在一起.另一件事是:因为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();
}
Run Code Online (Sandbox Code Playgroud)

在某些API中,存在异步函数的阻塞替代方案,但在这种情况下不是.

我感谢任何帮助.谢谢!

cha*_*lup 23

这样做的方法是使用嵌套的事件循环.您只需创建自己的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();
}
Run Code Online (Sandbox Code Playgroud)


Cal*_*itt 7

根据chalup回答,如果你要等待用户明显的时间,你可能想要显示一个进度条(或者可能是一个闪屏).

MyApp::MyApp(QWidget *parent) : ....
{
    doSomeInits();
    {
        QSpashScreen splash;
        splash.connect(configManager, SIGNAL(updateCompleted()), SLOT(close()));
        configManager->updateConfigurations(); 
        splash.exec();
    }
    doReaminingInitsThatHadToWaitForConfigMgr();
}
Run Code Online (Sandbox Code Playgroud)