当我等待返回值时,我想在后台执行一些繁重的任务,而不阻塞gui,使用QFutureWatcher,事情很简单。
Qt5.3文档中的示例
// Instantiate the objects and connect to the finished signal.
MyClass myObject;
QFutureWatcher<int> watcher;
connect(&watcher, SIGNAL(finished()), &myObject, SLOT(handleFinished()));
// Start the computation.
QFuture<int> future = QtConcurrent::run(...);
watcher.setFuture(future);在boost(我需要在主线程中执行handleFinished() )的帮助下,我如何能够生成类似于handleFinished的“已完成”信号?
虽然QFutureWatcher已经存在,但我们的项目现在依赖于Qt3、Qt4和Qt5 (从Qt3、Qt4升级到Qt5的优先级相当低),这就是为什么我们希望通过boost和标准库来实现后端任务。
编辑1:刚刚找到答案,boost::未来为这种场景提供了一个非常优雅的解决方案,只需使用future.then
future.then([](boost::future<int> f) { return print_value(f.get()); });编辑2:将来调用的函数在主线程中不执行,我如何使它成为主线程?
发布于 2014-06-12 19:18:45
如果希望在主线程中运行处理程序函数,则必须在事件循环中运行。
在这种情况下,你可以这样做:
(我使用C++11,但可以很容易地使用boost::thread或QThread)
struct Object:public QObject {
Q_OBJECT
std::thread thr;
Object(QObject *parent):QObject(parent){}
~Object(){
if(thr.joinable())
thr.join();
}
public slots:
void handler(int);
};
...
auto obj = new Object(parent); //store it somewhere
obj->thr=std::thread([](Object * obj){
int ret=run_something();
//PostEvent on the event queue where the obj Object resides
QMetaObject::invokeMethod(obj, "handler",
Qt::QueuedConnection,
Q_ARG(int,ret));
}
... 发布于 2014-06-09 09:09:31
为此您不需要任何库,特别是如果它是一次性的,而不是用于迭代之间的同步或类似的东西:
volatile bool done = false;
volatile int retvalue = 0;
void workerThread() {
retvalue = some_function_doing_math();
done = true;
}
void parentLocationCalling() {
done = false;
myCustomThread.run(workerThread);
for (;!done;) sleep(10);
// retvalue now contains the result
}如果您有C++11,那么就更容易完成了,因为您不需要任何特定于平台的代码(未经测试):
#include <thread>
void workerThread(int &ret) {
ret = some_function_doing_math();
}
void parentLocationCalling() {
int result;
std::thread worker(workerThread, std::ref(result));
worker.join();
}当然,您可能仍然希望在等待时处理窗口消息和/或更新窗口,在这些示例中没有考虑到这一点。
https://stackoverflow.com/questions/24114678
复制相似问题