QFutureWatcher未按预期触发信号,求助问题排查
问题原因及解决方案
你的代码存在三个关键问题,导致QFutureWatcher的信号无法触发:
1. 阻塞调用future.results()导致任务提前完成
future.results()会阻塞主线程直到异步任务完全结束,等你调用futureWatcher->setFuture(future)时,QFuture已经处于完成状态。QFutureWatcher不会回溯触发已经发生过的信号(比如finished或resultReadyAt)。
2. 缺少Qt事件循环
QFutureWatcher的信号依赖Qt事件循环来分发,你的main函数没有启动事件循环,即使任务异步完成,信号也无法被处理。
3. QtConcurrent::run用法错误
你无需手动使用QPromise返回结果,直接让lambda返回值即可,QtConcurrent::run会自动包装成QFuture。手动操作QPromise的方式在这里完全没必要,还容易出错。
修正后的代码
#include <QtDebug> #include <QtConcurrent> #include <QCoreApplication> int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); // 启动事件循环 QFutureWatcher<int> futureWatcher; // 栈分配,无需手动管理内存 QObject::connect(&futureWatcher, &QFutureWatcher<int>::resultReadyAt, [](int index) { qInfo() << "Result ready at index:" << index; }); QObject::connect(&futureWatcher, &QFutureWatcher<int>::finished, []() { qInfo() << "Future finished"; QCoreApplication::quit(); // 任务完成后退出事件循环 }); // 直接返回值,无需手动操作QPromise QFuture<int> future = QtConcurrent::run([]() { return 1; }); futureWatcher.setFuture(future); return app.exec(); // 启动事件循环 }
代码说明
- 用
QCoreApplication启动事件循环,确保信号能被正常分发处理。 - 移除阻塞的
future.results(),让任务异步执行,QFutureWatcher可以实时监听状态变化。 - 简化
QtConcurrent::run的用法,直接返回结果,避免手动操作QPromise的错误。 - 任务完成后调用
QCoreApplication::quit()退出事件循环,保证程序正常结束。
内容的提问来源于stack exchange,提问作者Toasdn
相关产品推荐
相关产品推荐

