c++ - Qt并发: Inform another function that result is ready

标签 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 完成的函数。

最佳答案

您可以从并发运行的函数发出自定义信号,或使用 QFutureWatcher 作为此类信号的来源。

例如当 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();
}

例如当 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();
    });
  }
}

例如取而代之的是 future 的观察者:

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

另见 this question .

关于c++ - Qt并发: Inform another function that result is ready,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44468849/

相关文章:

c++ - 有没有一种简单的方法可以在 C/C++ 中计算具有以下特征的 "smooth"函数?

c++ - 使用 C++ 编译器编译 C 代码会出现什么问题?

c++ - 3 个面板的 Qt 布局,全部垂直扩展以填充

c++ - 如何在下一个函数调用之前完全显示 QMessageBox

python - 用于动态输入形状的 Tensorflow C++ API

c++ - 使用 BYTE 类型的变量是否可移植?

c++ - 子函数中的内存栅栏 vs 与数据更改相同的函数

c++ - Qt 如何终止使用 startTimer() API 启动的计时器?

c++ - 是否可以从渲染线程强制执行主线程(GUI线程)?

c++ - Qt - LNK2019 在类的成员函数中使用命名空间的函数时