Is there a safe way to use Qt without calling QApplication::exec()?
I have a number of different objects that are carrying out long-lived processes on multiple resources (at least one of them is communicating with a web application server). I'm making a GUI application that prompts the user for input at the right time for these different processes. I'd like to have my 'flow' logic - the logic that determines what to do next - in one place and not in a GUI object like a dialog class. I was thinking that I could do something like this:
...
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();
...
Is this safe, from Qt's point of view? Is there a 'good' way of implementing magically_avoid_busywait_while_still_servicing_qt_somehow()
?
What I'm trying to accomplish here is to write our processing flow in the most explicit way possible. I'd like a single function that does this:
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
...
What I really want to avoid is kicking off and waiting for the processing inside Qt widgets and windows. Also, the processing objects themselves are entirely independent of Qt. I suppose what I'm trying to do is create a controller in a single function with a few helper callbacks and status variables.
What you want is an event loop other that the application's main event loop. This can be done using the 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()
While this is (in my eyes) clean code, this requires your netobject class to be a QObject and implement a signal done()
(which is also cleaner than providing callbacks).
Now you can wrap this whole code in a function which will be a blocking call on itself, so it can return some results from your dialog if you want so.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With