Submitting concurrent task via QFuture from GUI thread

453 views Asked by At

In order to avoid computations in GUI thread on button click I'm trying to run it in separate thread.

As soon as I want to have ability to monitor progress my code is based on this source.

So, my code is:

futureWatcher.setFuture(QtConcurrent::mapped(library_pool.cbegin(), library_pool.cend(), util->loadFilesInLibrary(library_pool)));

futureWatcher.waitForFinished();

table = QFuture::result(); 

Which is quite similar to the given sorce from qt docs, but it gives corresponding errors:

C2893: Failed to specialize function template 'QFuture<QtPrivate::MapResultType<void,MapFunctor>::ResultType> QtConcurrent::mapped(Iterator,Iterator,MapFunctor)'
C2780: 'QFuture<QtPrivate::MapResultType<void,MapFunctor>::ResultType> QtConcurrent::mapped(const Sequence &,MapFunctor)': expects 2 arguments - 3 provided
C2955: 'QFuture': use of class template requires template argument list
'QFuture<T>::result': illegal call of non-static member function

So, how do I properly populate worker thread(s) with function from non-gui class in button_clicked slot without making GUI hand?

UPD

Well, I've succeeded with compiling code for now and this is how it works:

futureWatcher.setFuture(QtConcurrent::run(&this->util, &Utils::loadFilesInLibrary, library_pool.at(0)));

futureWatcher.waitForFinished();

library_pool = future.result();

But button click still results to error in runtime: runtime error

My function which I'm trying to run generates no widgets, so the reason of this message is unclear.

I've read couple questions (like this) where all the code stated to work but it resides only in main() which is far from my needs. So, again, how do I start it from GUI thread?

1

There are 1 answers

0
Linville On

You can use non-static members with QtConcurrent methods with the help of a wrapper. There is more discussion about it at Qt's Forums. Here's another similar question asking about how to use the wrapper.

struct AddWrapper {
  Utils *utils = nullptr;
  typedef MyType result_type;

  AddWrapper(Util *u): instance(u) {};
  MyType operator()(const MyType &t) const {
    return instance->longMethod(t);
  }
}

Utils *foo = new Utils();
AddWrapper wrapper(foo);
QFuture<MyType> results = QtConcurrent::mapped(myList, wrapper);