【发布时间】:2012-10-03 23:27:33
【问题描述】:
有没有不调用 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 ms 的 QTimer 将在 gui 有机会的任何时候运行,并且可用于从其他线程收集信号以在 gui 线程上运行代码并避免任何线程地狱。因此,您的线程对象(QThread)可以执行它的业务并在需要输入时发出信号,然后自行停止。 gui 线程捕获该信号,提示用户,给线程结果。然后线程可以继续。还是我误会了?
-
我们的应用程序在 Qt 位和应用程序的其余部分之间有一条清晰的分界线。我们的大部分源文件(包括上面的 main 函数)都没有通过 moc 工具运行,并且无法发出或接收 Qt 信号。
-
虽然可以在 QApplication 的空闲时间之外执行此功能,但这意味着该功能必须重新进入,并且会变成一个丑陋的状态机。我希望的是一个可以从头到尾运行的单个函数——这将使程序流程非常明确。
-
我正在尝试寻找一种替代方法,以将
netobject传递给我们所有的 GUI 窗口和对话框并让它们启动处理(恕我直言,这隐藏了整个连接/处理流程)。跨度> -
信号和槽几乎是函数指针。您应该能够使用其中一个线程完成相同的事情。如果您从不调用 QApp::exec,我不完全确定 Qt 会做什么,我的猜测是它不会在意,但您可能需要检查源代码才能确定。
标签: c++ qt events user-interface