I'm developing an application where a user may parse some binary files. Once he clicks the "parse"-button, he first may select some files, which are parsed afterwards. While the application is processing the files, I'd like to display a modal dialog, which informs the user about the progress (QProgressBar bar) and the already parsed files (QListView list / listModel).
My current approach is to override the exec()-method of a QDialog-sublcass. This way I could just call
parseAssistant.exec()
The current implementation looks like this:
class ParseAssistant : public QDialog { public: int exec(); };
int ParseAssistant::exec()
{
bar->setMaximum(files.size());
this->show();
this->setModal(true);
for (int i = 0; i < files.size(); i++) {
PluginTable* table = parser.parse(files[i]);
// do something with the table
// saveTableintoDB();
// update GUI
// bar->setValue(i);
// listModel->insertRow(0, new QStandardItem(files[i]));
}
this->hide();
return QDialog::Accepted;
}
After this (blocking) method has run, the user either has parsed all files or canceled the progress somewhere. To achieve this I attempted to use QApplication::processEvents in the while-loop (which feels kinda laggy as it's only progressed when a file has finished parsing) or to outsource the heavy calculation(s) to some QConcurrent implementation (::run, ::mapped). Unfortunately, I don't know how to return the program flow back to the exec() method once the QFuture has finished without relying on some CPU-intense loop like:
while (!future.isFinished()) { QApplication::processEvents(); }
Is there a smarter approach to having a modal dialog, which runs a heavy calculation (which may be canceled by the user) without blocking the eventloop?