我是C ++和QT世界的新手。我需要对现有的控制台应用程序进行一些修改。
我遇到以下问题:我正在同时运行某些功能(需要一些时间)并在此期间显示等待指示器。设置如下:
QFuture<void> doStuff = QtConcurrent::run(longCalc, param1, param2);
showWaitIndicator(&doStuff);
// ....
void showWaitIndicator(QFuture<void> *future)
{
while (future->isRunning()) {
// Show some nice indicator and so on.
}
}
这个设置工作正常,但现在我想同时运行一些其他具有另一种返回类型的任务,我需要访问结果。这些QFuture<void>
,QFuture<double>
等代替QFuture<int>
而不是QFuture<double> doStuff = QtConcurrent::run(doubleCalc);
我也希望显示我的好等待指标,但不同的返回类型意味着我无法使用我当前的showWaitIndicator()
函数。
有没有一种改善这种“设置”的好方法?我是C ++的新手,所以我很确定必须有办法。我的第一个想法是函数重载但这不起作用,因为参数具有相同的类型(QFuture)。
TL; DR:我需要通知我的showWaitIndicator()
函数QFuture已完成。
答案 0 :(得分:1)
您可以从同时运行的函数发出自定义信号,或使用QFutureWatcher
作为此类信号的来源。
E.g。当longCalc
在同一个班级时:
MyClass::MyClass() {
Q_OBJECT
Q_SIGNAL void longCalcDone();
connect(this, &MyClass::longCalcDone, this, [this]{
...
});
}
void MyClass::longCalc(int arg1, int arg2) {
...
emit MyClass::longCalcDone();
}
E.g。当longCalc
是自由函数或在另一个类中时:
void longCalc(int, int);
MyClass::MyClass() {
Q_OBJECT
Q_SIGNAL void longCalcDone();
connect(this, &MyClass::longCalcDone, this, [this]{
...
});
void doStuff() {
QtConcurrent::run([=]{
longCalc(param1, param2);
emit longCalcDone();
});
}
}
E.g。与未来的观察者相反:
class MyClass : public QObject {
QFutureWatcher watcher;
MyClass() {
connect(&watcher, &QFutureWatcher::finished, this, [this]{
...
});
}
void doStuff() {
auto future = QtConcurrent::run(longCalc, this, param1, param2);
watcher.setFuture(&future);
}
};
while (future->isRunning())
同步代码是反模式。大概你在那个循环中调用QCoreApplication::processEvents
。问题是 - 世界不是那样的,你不能把控制点从事件循环中移开,假装世界围绕着你。相反,反转控制流程,并在未来完成时调用您的代码(插槽,方法或仿函数)。