0

I'm now adding GUI to a project original written for console operation. I chosen Qt as the framework and now facing difficulty in handling close event of QProgressDialog.

Issue 1: I used QtConcurrent::run to fork a process for a long/heavy task, and a 'waiting' QProgressDialog (range of 0,0) to hint user for a long running process. The problem is I cannot have the dialog to close itself!

void MainWindow::doLongRunProcess() {
  pDialog = new QProgressDialog("Loading 2 ...", "Abort", 0, 0, this);
  pDialog->setWindowModality(Qt::WindowModal);
  pDialog->show();
  QFuture<void> future = QtConcurrent::run(theApp, &SimApplication::runSimulation);
  QFutureWatcher<void> watcher;
  connect(&watcher,
        SIGNAL(finished()),
        this,
        SLOT(endLongRunProcess()));
  watcher.setFuture(future);
  // at this point, the runSimulation is successfully invoked
}

void MainWindow::endLongRunProcess()
{
  // no sign of being invoked!
  if (pDialog)
  {
      pDialog->close();
      delete pDialog;
  }
  logMessage("Operation completed");
}

Requirement 1: If possible, don't want to touch/change the code of the original package.

Issue 2: How to link the "abort" button to terminate the SimApplication::runSimulation()?

YamHon.CHAN
  • 866
  • 4
  • 20
  • 36
  • What does watcher.isFinished(); returns? You can add public slot to print status of watcher.isFinished(); to confirm it actually finishes... – Ilya Kobelevskiy Jan 21 '13 at 14:43
  • @IlyaKobelevskiy, in the runSimulation() call, i have debug printout which shown the call is ended. For watcher.isFinished(), how to setup the slot? – YamHon.CHAN Jan 21 '13 at 14:54
  • 1
    creating your watcher on the stack will have it destroyed right away at the end of the constructor. Try creating it on heap/make it a class member. – Frank Osterfeld Jan 21 '13 at 14:54
  • If you make watcher/pointer to watcher a class member as Frank Osterfeld mentioned, you can create public slot that prints watcher.isFinished(). Then you either link it to some button on your gui, or you can simply connect it to QTimer in MainWindow::doLongRunProcess() to query it status at given times.. – Ilya Kobelevskiy Jan 21 '13 at 15:00
  • @FrankOsterfeld, Thank for advance! How about the linkage to "abort" event? Any suggestion? – YamHon.CHAN Jan 21 '13 at 15:00
  • Is it good to reuse the 'watcher' variable (across the MainWindow) for multiple unrelated, never called at the same time, methods? – YamHon.CHAN Jan 21 '13 at 15:04
  • You cannot cancel a function called via run(), see QFuture::cancel(). You can a) either just let it finish and ignore the result or b) implement it differently. – Frank Osterfeld Jan 21 '13 at 21:25

1 Answers1

1

Try calling setAttribute(Qt::WA_DeleteOnClose, true) on the dialog after you create it and attach finished() to the dialog's close() slot instead of your slot. The dialog will delete itself when it's appropriate to do so the way QObject::deleteLater() would have.

cppguy
  • 3,611
  • 2
  • 21
  • 36