c++qtqt5progressqtconcurrent

How to communicate a progressText from a QtConcurrent::run function (or similar) to a QFutureWatcher?


If I launch some function for asynchronous execution using QtConcurrent::run, and am monitoring the returned future using a QFutureWatcher, what if anything can I do in that asynchronously executing function to communicate some progress text back which will result in the QFutureWatcher firing its progressTextChanged signal?

ie what I want to do is something like:

void fn() {
  ???->setProgressText("Starting);
  ...
  ???->setProgressText("halfway");
  ...
  ???->setProgressText("done!");
}

QFutureWatcher watcher;
connect(&watcher, SIGNAL(progressTextChanged(const QString&)), &someGuiThing, SLOT(updateProgress(const QString&)));
connect(&watcher, SIGNAL(finished(), &someGuiThing, SLOT(doStuff()));
QFuture<void> future=QConcurrent::run(fn);
watcher.setFuture(future);

However, big problem, the QtConcurrent::run documentation clearly states

Note that the QFuture returned by QtConcurrent::run() does not support canceling, pausing, or progress reporting. The QFuture returned can only be used to query for the running/finished status and the return value of the function.

So what's the simplest thing I can do which will get me something functionally equivalent to what the above is trying to do? Do I have to abandon QtConcurrent::run? QFuture? Both? (And go back to QThread and queued connections?)


Solution

  • QFuture returned by QtConcurrent functions like QtConcurrent::mappedReduced() have progress information provided by the progressValue(), progressMinimum(), progressMaximum(), and progressText() functions. Unlike QtConcurrent::run() which does not provide such a thing automatically.

    QtConcurrent::run() does not provide progress information automatically like QtConcurrent::mappedReduced(). But you can have your own progress reporting mechanism using signals. I don't think there is any other way which is straightforward.