You can still use QFutureWatcher
with QProgressDialog
like in my example:
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();
}