Andy
Andy

Reputation: 3839

How can I watch more than one QFuture?

The QFutureWatcher class emits the signal finished() when the QFuture it is watching has finished. How can I watch more than one QFuture? I am running two threads in parallel using QtConcurrent::run() and would like to get a signal when both threads have finished.

Upvotes: 1

Views: 937

Answers (2)

scopchanov
scopchanov

Reputation: 8419

I would approach the problem like this:

  1. Create as many QFutureWatchers as needed

  2. Add all QFutureWatchers to a list, resp. vector, e.g. m_futureWatchers:

     m_futureWatchers.append(futureWatcher);
    
  3. Connect the QFutureWatcher::finished signals to the same slot, e.g. handleFinished:

     connect(futureWatcher, &QFutureWatcher<int>::finished, this, MyClass::handleFinished);
    
  4. In the handleFinished slot check QFutureWatcher::isFinished and react accordingly:

     bool allAreFinished = true;
    
     for (auto *futureWatcher : m_futureWatchers)
         allAreFinished &= futureWatcher->isFinished();
    
     if (allAreFinished) {
         // doSomething
     }
    

Note: For only two future watchers, it might be easier to have two member variables, e.g. m_futureWatcher1 and m_futureWatcher1, instead of a list, and check them in the handleFinished slot like this:

if (m_futureWatcher1->isFinished() && m_futureWatcher2->isFinished) {
    ...
}

Upvotes: 2

Vladimir Bershov
Vladimir Bershov

Reputation: 2832

You can use 3rd party AsyncFuture library for Qt:

Combine multiple futures with different type into a single future object:

/* Combine multiple futures with different type into a single future */

QFuture<QImage> f1 = QtConcurrent::run(readImage, QString("image.jpg"));

QFuture<void> f2 = observe(timer, &QTimer::timeout).future();

QFuture<QImage> result = (combine() << f1 << f2).subscribe([=](){
    // Read an image but do not return before timeout
    return f1.result();
}).future();

QCOMPARE(result.progressMaximum(), 2);

Upvotes: 2

Related Questions