Отправка параллельной задачи через QFuture из потока GUI

Чтобы избежать вычислений в потоке графического интерфейса при нажатии кнопки, я пытаюсь запустить его в отдельном потоке.

Как только я хочу иметь возможность отслеживать прогресс, мой код основан на этом источнике.

Итак, мой код:

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

futureWatcher.waitForFinished();

table = QFuture::result(); 

Что очень похоже на данное сообщение из qt docs, но дает соответствующие ошибки:

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

Итак, как правильно заполнить рабочий поток (ы) с функцией из не-графического класса в button_clicked слот, не делая руки GUI?

UPD

Что ж, сейчас мне удалось скомпилировать код, и вот как он работает:

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

futureWatcher.waitForFinished();

library_pool = future.result();

Но нажатие кнопки все равно приводит к ошибке во время выполнения: ошибка выполнения

Моя функция, которую я пытаюсь запустить, не генерирует виджеты, поэтому причина этого сообщения неясна.

Я прочитал пару вопросов (вроде этого), где весь код, указанный для работы, но он находится только в main() что далеко от моих потребностей. Итак, опять же, как мне запустить его из потока GUI?

2 ответа

QtConcurrent::map(), QtConcurrent::mapped(), QtConcurrent::mappedReduced() и QtConcurrent:: run () принимают указатели на функции-члены. Тип класса функции-члена должен соответствовать типу, сохраненному в последовательности

 QFuture<void> future = QtConcurrent::run(&this->MyObject, &MyClass::LongFunction, val1, val2, val3);

Я думаю, что ваша проблема в этом

Вы можете использовать нестатические члены с методами QtConcurrent с помощью оболочки. Это обсуждается на форумах Qt. Вот еще один похожий вопрос о том, как использовать обертку.

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);
Другие вопросы по тегам