有没有一种安全的方法可以在不调用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 :(得分: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()
(它比提供回调更清晰)。
现在你可以将整个代码包装在一个函数中,这个函数本身就是一个阻塞调用,所以如果你愿意,它可以从你的对话框中返回一些结果。