Consider:
class Worker
{
public:
void DoWork();
};
class MainWindow : public QMainWindow
{
Q_OBJECT
private:
Worker MyWorker;
public:
void DoWork();
};
I want the DoWork
function of my MainWindow
to behave like:
void MainWindow::DoWork()
{
setEnabled(false);
std::future<void> Resu = std::async(std::launch::async, &Worker::DoWork, &MyWorker);
while (Resu.wait_for(100ms) == std::future_status::timeout)
qApp->processEvents();
try
{ Resu.get(); }
catch (Except const &MyExcept)
{ QMessageBox::critical(this, "Error", MyExcept.What()); }
setEnabled(true);
}
This works as I want: (i) the window is disabled while doing the work,
(ii) the window stays responsive while doing the work (can be moved and resized), and (iii) any
Except
thrown in Worker::DoWork
is caught conveniently.
However, this solution relies upon std::future
and qApp->processEvents()
, the latter
not being recommended by this answer.
How can I write the above code properly in Qt?
So far, I have tried:
void MainWindow::DoWork()
{
setEnabled(false);
QFuture<void> Resu = QtConcurrent::run(std::bind(&Worker::DoWork, &MyWorker));
try
{ while (Resu.isRunning()) qApp->processEvents(); }
catch (Except const &MyExcept)
{ QMessageBox::critical(this, "Error", MyExcept.What()); }
setEnabled(true);
}
and I found the drawbacks of consuming a whole thread (because the too frequent calls to qApp->processEvents()
), and furthermore the exceptions are not properly caught.