QtConcurrent:通知另一个结果准备就绪的函数

时间:2017-06-10 02:06:59

标签: c++ qt

我是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已完成。

1 个答案:

答案 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。问题是 - 世界不是那样的,你不能把控制点从事件循环中移开,假装世界围绕着你。相反,反转控制流程,并在未来完成时调用您的代码(插槽,方法或仿函数)。

另见this question