如果我使用QtConcurrent::run启动一些用于异步执行的函数,并且正在使用一个QFutureWatcher监视返回的未来,那么在这个异步执行的函数中,我可以做什么来将一些进度文本传送回来,这将导致QFutureWatcher触发它的progressTextChanged信号?
我想做的是:
void fn() {
???->setProgressText("Starting);
...
???->setProgressText("halfway");
...
???->setProgressText("done!");
}
QFutureWatcher watcher;
connect(&watcher, SIGNAL(progressTextChanged(const QString&)), &someGuiThing, SLOT(updateProgress(const QString&)));
connect(&watcher, SIGNAL(finished(), &someGuiThing, SLOT(doStuff()));
QFuture<void> future=QConcurrent::run(fn);
watcher.setFuture(future);然而,大问题,QtConcurrent::run 文档清楚地声明
注意,QtConcurrent::run()返回的QFuture不支持取消、暂停或进度报告。返回的QFuture只能用于查询运行/完成状态和函数的返回值。
那么,我能做的最简单的事情是什么,它能给我一些功能上相当于上面所试图做的事情的东西?我必须放弃QtConcurrent::run吗?QFuture?两者都有?(然后返回到QThread和排队连接?)
发布于 2014-05-03 03:43:23
由QFuture等QtConcurrent函数返回的QtConcurrent::mappedReduced()具有由progressValue()、progressMinimum()、progressMaximum()和progressText()函数提供的进度信息。与QtConcurrent::run()不同的是,它不会自动提供这样的东西。
QtConcurrent::run()不像QtConcurrent::mappedReduced()那样自动提供进度信息。但是,您可以使用信号建立自己的进度报告机制。我不认为有任何其他的方法是直接的。
发布于 2021-09-10 11:29:38
在我的示例中,仍然可以将QFutureWatcher与QProgressDialog一起使用:
void hole_mark::get_frames_with_progress(const QString& movie, const QString& output) {
Ptr<cv::VideoCapture> source = makePtr<VideoCapture>(movie.toUtf8().constData());
auto frames = (int)(source->get(CAP_PROP_FRAME_COUNT));
QProgressDialog dialog(tr("Importing frames: %1...").arg(frames), tr("Cancel"), 0, frames, this);
dialog.setWindowModality(Qt::WindowModal);
QFutureWatcher<void> futureWatcherProgress;
QFutureInterface<void> promise;
QFuture<void> future = promise.future();
promise.reportStarted();
QObject::connect(&futureWatcherProgress, SIGNAL(finished()), &dialog, SLOT(reset()));
QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcherProgress, SLOT(cancel()));
QObject::connect(&futureWatcherProgress, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));
QObject::connect(&futureWatcherProgress, SIGNAL(progressRangeChanged(int, int)), &dialog, SLOT(setRange(int, int)));
QObject::connect(&futureWatcherProgress, SIGNAL(progressTextChanged(const QString&)), &dialog, SLOT(setLabelText(const QString&)));
futureWatcherProgress.setFuture(future);
promise.setThreadPool(QThreadPool::globalInstance());
auto runnable = QRunnable::create([&, frames, source]() {
promise.setProgressRange(0, frames);
promise.setProgressValue(0);
cv::Mat m;
int frame = 0;
while (!future.isCanceled()) {
*source >> m;
if (m.empty()) {
break;
}
promise.setProgressValueAndText(++frame, tr("Importing %1 frame from: %2...").arg(frame).arg(frames));
qDebug() << "frame: " << frame;
}
promise.reportFinished();
});
promise.setRunnable(runnable);
QThreadPool::globalInstance()->start(runnable);
// Display the dialog and start the event loop.
dialog.exec();
futureWatcherProgress.waitForFinished();
// Query the future to check if was canceled.
qDebug() << "Canceled?" << futureWatcherProgress.future().isCanceled();
}https://stackoverflow.com/questions/23438044
复制相似问题