Skip to content

Instantly share code, notes, and snippets.

@MaartenBaert
Created October 9, 2017 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MaartenBaert/e9c94f8c57cdb2913fe21102b9a6293d to your computer and use it in GitHub Desktop.
Save MaartenBaert/e9c94f8c57cdb2913fe21102b9a6293d to your computer and use it in GitHub Desktop.
QProgressDialog with separate worker thread. Note that there's a possible reentrancy problem since setValue calls QApplication::processEvents.
QProgressDialog dialog("Parameter sweep ...", "Cancel", 0, (int) sweep_values.size(), this);
dialog.setWindowTitle(MainWindow::WINDOW_CAPTION);
dialog.setWindowModality(Qt::WindowModal);
dialog.setMinimumDuration(0);
dialog.setValue(0);
std::atomic<bool> worker_canceled(false), worker_stopped(false);
std::exception_ptr worker_exception;
std::thread worker_thread([&]() {
try {
for(size_t i = 0; i < sweep_values.size(); ++i) {
if(worker_canceled) {
throw std::runtime_error("Parameter sweep canceled by user.");
}
context.m_parameters[param_index].Value() = FloatScale(sweep_values[i]);
tline_type.m_simulate(context);
std::copy(context.m_results.begin(), context.m_results.end(), combined_results.begin() + TLINERESULT_COUNT * tline_type.m_modes.size() * i);
bool res = QMetaObject::invokeMethod(&dialog, "setValue", Qt::QueuedConnection, Q_ARG(int, (int) i + 1));
}
} catch(...) {
worker_exception = std::current_exception();
}
worker_stopped = true;
});
try {
while(!worker_stopped) {
QApplication::processEvents(QEventLoop::WaitForMoreEvents);
if(dialog.wasCanceled()) {
worker_canceled = true;
break;
}
}
} catch(...) {
worker_canceled = true;
worker_thread.join();
throw;
}
worker_thread.join();
if(worker_exception) {
std::rethrow_exception(worker_exception);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment