Как передать progressText из функции QtConcurrent::run (или аналогичной) в QFutureWatcher?

Если я запускаю какую-то функцию для асинхронного выполнения, используя 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 документация четко указывает

Обратите внимание, что QFuture, возвращаемый QtConcurrent::run(), не поддерживает отмену, приостановку или отчеты о ходе выполнения. Возвращенный QFuture может использоваться только для запроса статуса выполнения/завершения и возвращаемого значения функции.

Итак, что самое простое, что я могу сделать, что даст мне что-то функционально эквивалентное тому, что пытается сделать выше? Должен ли я отказаться от QtConcurrent::run? QFuture? Оба? (И вернуться к QThread и соединениям в очереди?)


person timday    schedule 02.05.2014    source источник


Ответы (1)


QFuture, возвращаемый функциями QtConcurrent, такими как QtConcurrent::mappedReduced(), имеет информацию о ходе выполнения, предоставленную функциями progressValue(), progressMinimum(), progressMaximum() и progressText(). В отличие от QtConcurrent::run(), который автоматически этого не предоставляет.

QtConcurrent::run() не предоставляет информацию о прогрессе автоматически, как QtConcurrent::mappedReduced(). Но вы можете иметь свой собственный механизм отчетов о прогрессе, используя сигналы. Я не думаю, что есть какой-то другой прямой путь.

person Nejat    schedule 03.05.2014
comment
Хорошо, но тогда что я на самом деле вызываю в fn(), чтобы получить информацию о прогрессе для обновления? Очевидно, в него нужно что-то передать... но что? Кажется, существует QFutureInterfaceBase, в котором есть методы настройки информации о прогрессе, но QFuture фактически не наследует его. Хммм... очевидно, следующий шаг - посмотреть на реализацию QtConcurrent::mappedReduced() и посмотреть, как она это делает... - person timday; 03.05.2014
comment
Я думаю, что использование сигналов для сообщения о прогрессе является наиболее удобным способом при использовании QtConcurrent::run(). - person Nejat; 03.05.2014
comment
Да, это то, что я в итоге сделал: отправка сообщений о состоянии из параллельной функции с использованием QMetaObject::invokeMethod с QueuedConnection в слот, отслеживающий его ход (на самом деле, BlockingQueuedConnection, казалось, привел к более плавному отображению... Я отправляю много сообщений). Немного больше о контексте на qt-project.org/forums/viewthread/41012/# 174738 - person timday; 03.05.2014