从GUI线程

时间:2017-07-17 17:45:49

标签: c++ multithreading qt user-interface qfuture

为了避免按钮点击GUI线程中的计算,我试图在单独的线程中运行它。

只要我希望能够监控进度,我的代码就会基于this来源。

所以,我的代码是:

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

futureWatcher.waitForFinished();

table = QFuture::result(); 

这与来自qt docs的给定的sorce非常相似,但它给出了相应的错误:

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类的函数正确填充工作线程而不用GUI手?

UPD

嗯,我现在已成功编译代码,这就是它的工作原理:

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

futureWatcher.waitForFinished();

library_pool = future.result();

但按钮单击仍会导致运行时出错: runtime error

我尝试运行的功能不会生成任何小部件,因此此消息的原因尚不清楚。

我已经阅读了几个问题(例如this),其中所有代码都说明有效,但它只存在于main(),这远远不是我的需要。那么,再次,我如何从GUI线程启动它?

2 个答案:

答案 0 :(得分:0)

QtConcurrent :: map(),QtConcurrent :: mapped(),QtConcurrent :: mappedReduced()和QtConcurrent :: run()接受指向成员函数的指针。成员函数类类型必须与序列

中存储的类型匹配
 QFuture<void> future = QtConcurrent::run(&this->MyObject, &MyClass::LongFunction, val1, val2, val3);

我认为你的问题是这个

答案 1 :(得分:0)

您可以在包装器的帮助下将非静态成员与QtConcurrent方法一起使用。在Qt's Forums有更多关于它的讨论。 Here's another similar question询问如何使用包装器。

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);