2012-10-03 221 views
4

有没有一种安全的方式来使用Qt而不调用QApplication :: exec()?有没有办法在没有QApplication :: exec()的情况下使用Qt?

我有很多不同的对象在多个资源(至少其中一个正在与Web应用程序服务器通信)上执行长寿命进程。我正在制作一个GUI应用程序,提示用户在正确的时间输入这些不同的进程。我希望在一个地方有我的'流'逻辑 - 确定下一步要做什么的逻辑,而不是像对话类那样的GUI对象。我在想我可以这样做:

... 

wait_dialog dlg; 
dlg.setModal(false); 
dlg.show(); // Should return... 

netobject.start_long_lived_process_that_happens_on_other_thread(&completion_callback); 
while (!completion_callback_called()) 
{ 
    qApp->processEvents(); 
    netobject.pump_callbacks(); 
    magically_avoid_busywait_while_still_servicing_qt_somehow(); 
} 

dlg.hide(); 

... 

从Qt的角度来看,这是安全吗?实施magically_avoid_busywait_while_still_servicing_qt_somehow()有没有“好”的方法?

我想在这里完成的是以最明确的方式编写我们的处理流程。我想一个单一的功能,这是否:

show_a_non_modal_wait_dialog() 

start_some_processing_1() 

wait_for_processing_1_to_finish() 

dismiss_non_modal_wait_dialog() 

show_modal_input_dialog() 

if (cancelled) return 

show_a_non_modal_wait_dialog() 

start_some_processing_2() 

wait_for_processing_2_to_finish() 

dismiss_non_modal_wait_dialog() 

show_modal_input_dialog() 

if (cancelled) return 

... 

我真的想避免是蹬掉,并等待Qt控件和窗口内的处理。另外,处理对象本身完全独立于Qt。我想我正在尝试做的是用一个辅助回调和状态变量在一个函数中创建一个控制器。

+0

我想我不知道为什么你需要暂停事件处理。我相信设置为0毫秒的QTimer会在gui有机会时运行,并且可以用来从其他线程收集信号以在gui线程上运行代码并避免任何线程死亡。所以你是线程对象(QThread)可以处理它的业务,并在需要输入时发出信号,然后停止自己。 gui线程捕获该信号,提示用户,给线程结果。然后该线程可以继续。或者我误解了? – Thadeux

+0

我们的应用程序在Qt-bits和我们其他应用程序之间有明确的分界线。我们的大多数源文件(包括上面的主函数)都没有通过moc工具运行,也不能发送或接收Qt信号。 –

+0

尽管挂起QApplication的空闲时间可能会执行此功能,但这意味着该功能必须重新输入,并且会成为一个丑陋的状态机器。我所希望的是一个可以从头到尾运行的单一功能 - 这将使程序流程非常明确。 –

回答

5

你想要的是一个事件循环,也就是应用程序的主事件循环。这可以通过使用QEventLoop来完成:

wait_dialog dlg; 
dlg.setModal(false); 
dlg.show(); // Should return... 

QEventLoop loop; 
connect(&netobject, SIGNAL(done()), &loop, SLOT(quit())); 
netobject.start_long_lived_process_that_happens_on_other_thread(); 

loop.exec(); // BLOCKING (non-busy) until quit() is called via the signal done() 

虽然这是(在我眼里)干净的代码,这需要你的netobject类是一个QObject和实施的信号done()(这也是不是提供回调清洁剂)。

现在,您可以将这整个代码包装在一个函数中,这个函数本身就是一个阻塞调用,所以如果需要的话,它可以从对话框中返回一些结果。

+0

啊,既然你扩展了关于该对象不是Qt相关信息的问题,我想补充一点,你也可以创建一个回调方法,只是退出一个特定的QEventLoop而不是做这个连接。这基本上是一样的。 – leemes

+0

我打算把这个标记为'答案'。我喜欢它完全避免了processEvents()这似乎有点狡猾,似乎有一些我不明白的危险异常(如DeferredDelete事件?)。 –

+0

你不知道这对我有多大帮助! – Luca

相关问题