1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qfuturewatcher.h" |
5 | #include "qfuturewatcher_p.h" |
6 | |
7 | #include <QtCore/qcoreevent.h> |
8 | #include <QtCore/qcoreapplication.h> |
9 | #include <QtCore/qmetaobject.h> |
10 | #include <QtCore/qthread.h> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | /*! \class QFutureWatcher |
15 | \reentrant |
16 | \since 4.4 |
17 | |
18 | \inmodule QtCore |
19 | \ingroup thread |
20 | |
21 | \brief The QFutureWatcher class allows monitoring a QFuture using signals |
22 | and slots. |
23 | |
24 | QFutureWatcher provides information and notifications about a QFuture. Use |
25 | the setFuture() function to start watching a particular QFuture. The |
26 | future() function returns the future set with setFuture(). |
27 | |
28 | For convenience, several of QFuture's functions are also available in |
29 | QFutureWatcher: progressValue(), progressMinimum(), progressMaximum(), |
30 | progressText(), isStarted(), isFinished(), isRunning(), isCanceled(), |
31 | isSuspending(), isSuspended(), waitForFinished(), result(), and resultAt(). |
32 | The cancel(), setSuspended(), suspend(), resume(), and toggleSuspended() functions |
33 | are slots in QFutureWatcher. |
34 | |
35 | Status changes are reported via the started(), finished(), canceled(), |
36 | suspending(), suspended(), resumed(), resultReadyAt(), and resultsReadyAt() |
37 | signals. Progress information is provided from the progressRangeChanged(), |
38 | void progressValueChanged(), and progressTextChanged() signals. |
39 | |
40 | Throttling control is provided by the setPendingResultsLimit() function. |
41 | When the number of pending resultReadyAt() or resultsReadyAt() signals |
42 | exceeds the limit, the computation represented by the future will be |
43 | throttled automatically. The computation will resume once the number of |
44 | pending signals drops below the limit. |
45 | |
46 | Example: Starting a computation and getting a slot callback when it's |
47 | finished: |
48 | |
49 | \snippet code/src_corelib_thread_qfuturewatcher.cpp 0 |
50 | |
51 | Be aware that not all running asynchronous computations can be canceled or |
52 | suspended. For example, the future returned by QtConcurrent::run() cannot be |
53 | canceled; but the future returned by QtConcurrent::mappedReduced() can. |
54 | |
55 | QFutureWatcher<void> is specialized to not contain any of the result |
56 | fetching functions. Any QFuture<T> can be watched by a |
57 | QFutureWatcher<void> as well. This is useful if only status or progress |
58 | information is needed; not the actual result data. |
59 | |
60 | \sa QFuture, {Qt Concurrent} |
61 | */ |
62 | |
63 | /*! \fn template <typename T> QFutureWatcher<T>::QFutureWatcher(QObject *parent) |
64 | |
65 | Constructs a new QFutureWatcher with the given \a parent. Until a future is |
66 | set with setFuture(), the functions isStarted(), isCanceled(), and |
67 | isFinished() return \c true. |
68 | */ |
69 | QFutureWatcherBase::QFutureWatcherBase(QObject *parent) |
70 | :QObject(*new QFutureWatcherBasePrivate, parent) |
71 | { } |
72 | |
73 | /*! \fn template <typename T> QFutureWatcher<T>::~QFutureWatcher() |
74 | |
75 | Destroys the QFutureWatcher. |
76 | */ |
77 | |
78 | /*! \fn template <typename T> void QFutureWatcher<T>::cancel() |
79 | |
80 | Cancels the asynchronous computation represented by the future(). Note that |
81 | the cancellation is asynchronous. Use waitForFinished() after calling |
82 | cancel() when you need synchronous cancellation. |
83 | |
84 | Currently available results may still be accessed on a canceled QFuture, |
85 | but new results will \e not become available after calling this function. |
86 | Also, this QFutureWatcher will not deliver progress and result ready |
87 | signals once canceled. This includes the progressValueChanged(), |
88 | progressRangeChanged(), progressTextChanged(), resultReadyAt(), and |
89 | resultsReadyAt() signals. |
90 | |
91 | Be aware that not all running asynchronous computations can be canceled. |
92 | For example, the QFuture returned by QtConcurrent::run() cannot be |
93 | canceled; but the QFuture returned by QtConcurrent::mappedReduced() can. |
94 | */ |
95 | void QFutureWatcherBase::cancel() |
96 | { |
97 | futureInterface().cancel(); |
98 | } |
99 | |
100 | #if QT_DEPRECATED_SINCE(6, 0) |
101 | /*! \fn template <typename T> void QFutureWatcher<T>::setPaused(bool paused) |
102 | |
103 | \deprecated [6.6] Use setSuspended() instead. |
104 | |
105 | If \a paused is true, this function pauses the asynchronous computation |
106 | represented by the future(). If the computation is already paused, this |
107 | function does nothing. QFutureWatcher will not immediately stop delivering |
108 | progress and result ready signals when the future is paused. At the moment |
109 | of pausing there may still be computations that are in progress and cannot |
110 | be stopped. Signals for such computations will still be delivered after |
111 | pause. |
112 | |
113 | If \a paused is false, this function resumes the asynchronous computation. |
114 | If the computation was not previously paused, this function does nothing. |
115 | |
116 | Be aware that not all computations can be paused. For example, the |
117 | QFuture returned by QtConcurrent::run() cannot be paused; but the QFuture |
118 | returned by QtConcurrent::mappedReduced() can. |
119 | |
120 | \sa suspend(), resume(), toggleSuspended() |
121 | */ |
122 | void QFutureWatcherBase::setPaused(bool paused) |
123 | { |
124 | futureInterface().setSuspended(paused); |
125 | } |
126 | |
127 | /*! \fn template <typename T> void QFutureWatcher<T>::pause() |
128 | |
129 | \deprecated |
130 | Use suspend() instead. |
131 | |
132 | Pauses the asynchronous computation represented by the future(). This is a |
133 | convenience method that simply calls setPaused(true). |
134 | |
135 | \sa resume() |
136 | */ |
137 | void QFutureWatcherBase::pause() |
138 | { |
139 | futureInterface().setSuspended(true); |
140 | } |
141 | |
142 | #endif // QT_DEPRECATED_SINCE(6, 0) |
143 | |
144 | /*! \fn template <typename T> void QFutureWatcher<T>::setSuspended(bool suspend) |
145 | |
146 | \since 6.0 |
147 | |
148 | If \a suspend is true, this function suspends the asynchronous computation |
149 | represented by the future(). If the computation is already suspended, this |
150 | function does nothing. QFutureWatcher will not immediately stop delivering |
151 | progress and result ready signals when the future is suspended. At the moment |
152 | of suspending there may still be computations that are in progress and cannot |
153 | be stopped. Signals for such computations will still be delivered. |
154 | |
155 | If \a suspend is false, this function resumes the asynchronous computation. |
156 | If the computation was not previously suspended, this function does nothing. |
157 | |
158 | Be aware that not all computations can be suspended. For example, the |
159 | QFuture returned by QtConcurrent::run() cannot be suspended; but the QFuture |
160 | returned by QtConcurrent::mappedReduced() can. |
161 | |
162 | \sa suspend(), resume(), toggleSuspended() |
163 | */ |
164 | void QFutureWatcherBase::setSuspended(bool suspend) |
165 | { |
166 | futureInterface().setSuspended(suspend); |
167 | } |
168 | |
169 | /*! \fn template <typename T> void QFutureWatcher<T>::suspend() |
170 | |
171 | \since 6.0 |
172 | |
173 | Suspends the asynchronous computation represented by this future. This is a |
174 | convenience method that simply calls setSuspended(true). |
175 | |
176 | \sa resume() |
177 | */ |
178 | void QFutureWatcherBase::suspend() |
179 | { |
180 | futureInterface().setSuspended(true); |
181 | } |
182 | |
183 | /*! \fn template <typename T> void QFutureWatcher<T>::resume() |
184 | |
185 | Resumes the asynchronous computation represented by the future(). This is |
186 | a convenience method that simply calls setSuspended(false). |
187 | |
188 | \sa suspend() |
189 | */ |
190 | |
191 | void QFutureWatcherBase::resume() |
192 | { |
193 | futureInterface().setSuspended(false); |
194 | } |
195 | |
196 | #if QT_DEPRECATED_SINCE(6, 0) |
197 | /*! \fn template <typename T> void QFutureWatcher<T>::togglePaused() |
198 | |
199 | \deprecated [6.0] Use toggleSuspended() instead. |
200 | |
201 | Toggles the paused state of the asynchronous computation. In other words, |
202 | if the computation is currently paused, calling this function resumes it; |
203 | if the computation is running, it is paused. This is a convenience method |
204 | for calling setPaused(!isPaused()). |
205 | |
206 | \sa setSuspended(), suspend(), resume() |
207 | */ |
208 | void QFutureWatcherBase::togglePaused() |
209 | { |
210 | futureInterface().toggleSuspended(); |
211 | } |
212 | #endif // QT_DEPRECATED_SINCE(6, 0) |
213 | |
214 | /*! \fn template <typename T> void QFutureWatcher<T>::toggleSuspended() |
215 | |
216 | \since 6.0 |
217 | |
218 | Toggles the suspended state of the asynchronous computation. In other words, |
219 | if the computation is currently suspending or suspended, calling this |
220 | function resumes it; if the computation is running, it is suspended. This is a |
221 | convenience method for calling setSuspended(!(isSuspending() || isSuspended())). |
222 | |
223 | \sa setSuspended(), suspend(), resume() |
224 | */ |
225 | void QFutureWatcherBase::toggleSuspended() |
226 | { |
227 | futureInterface().toggleSuspended(); |
228 | } |
229 | |
230 | /*! \fn template <typename T> int QFutureWatcher<T>::progressValue() const |
231 | |
232 | Returns the current progress value, which is between the progressMinimum() |
233 | and progressMaximum(). |
234 | |
235 | \sa progressMinimum(), progressMaximum() |
236 | */ |
237 | int QFutureWatcherBase::progressValue() const |
238 | { |
239 | return futureInterface().progressValue(); |
240 | } |
241 | |
242 | /*! \fn template <typename T> int QFutureWatcher<T>::progressMinimum() const |
243 | |
244 | Returns the minimum progressValue(). |
245 | |
246 | \sa progressValue(), progressMaximum() |
247 | */ |
248 | int QFutureWatcherBase::progressMinimum() const |
249 | { |
250 | return futureInterface().progressMinimum(); |
251 | } |
252 | |
253 | /*! \fn template <typename T> int QFutureWatcher<T>::progressMaximum() const |
254 | |
255 | Returns the maximum progressValue(). |
256 | |
257 | \sa progressValue(), progressMinimum() |
258 | */ |
259 | int QFutureWatcherBase::progressMaximum() const |
260 | { |
261 | return futureInterface().progressMaximum(); |
262 | } |
263 | |
264 | /*! \fn template <typename T> QString QFutureWatcher<T>::progressText() const |
265 | |
266 | Returns the (optional) textual representation of the progress as reported |
267 | by the asynchronous computation. |
268 | |
269 | Be aware that not all computations provide a textual representation of the |
270 | progress, and as such, this function may return an empty string. |
271 | */ |
272 | QString QFutureWatcherBase::progressText() const |
273 | { |
274 | return futureInterface().progressText(); |
275 | } |
276 | |
277 | /*! \fn template <typename T> bool QFutureWatcher<T>::isStarted() const |
278 | |
279 | Returns \c true if the asynchronous computation represented by the future() |
280 | has been started, or if no future has been set; otherwise returns \c false. |
281 | */ |
282 | bool QFutureWatcherBase::isStarted() const |
283 | { |
284 | return futureInterface().queryState(state: QFutureInterfaceBase::Started); |
285 | } |
286 | |
287 | /*! \fn template <typename T> bool QFutureWatcher<T>::isFinished() const |
288 | |
289 | Returns \c true if the asynchronous computation represented by the future() |
290 | has finished, or if no future has been set; otherwise returns \c false. |
291 | */ |
292 | bool QFutureWatcherBase::isFinished() const |
293 | { |
294 | return futureInterface().isFinished(); |
295 | } |
296 | |
297 | /*! \fn template <typename T> bool QFutureWatcher<T>::isRunning() const |
298 | |
299 | Returns \c true if the asynchronous computation represented by the future() |
300 | is currently running; otherwise returns \c false. |
301 | */ |
302 | bool QFutureWatcherBase::isRunning() const |
303 | { |
304 | return futureInterface().queryState(state: QFutureInterfaceBase::Running); |
305 | } |
306 | |
307 | /*! \fn template <typename T> bool QFutureWatcher<T>::isCanceled() const |
308 | |
309 | Returns \c true if the asynchronous computation has been canceled with the |
310 | cancel() function, or if no future has been set; otherwise returns \c false. |
311 | |
312 | Be aware that the computation may still be running even though this |
313 | function returns \c true. See cancel() for more details. |
314 | */ |
315 | bool QFutureWatcherBase::isCanceled() const |
316 | { |
317 | return futureInterface().queryState(state: QFutureInterfaceBase::Canceled); |
318 | } |
319 | |
320 | #if QT_DEPRECATED_SINCE(6, 0) |
321 | |
322 | /*! \fn template <typename T> bool QFutureWatcher<T>::isPaused() const |
323 | |
324 | \deprecated [6.0] Use isSuspending() or isSuspended() instead. |
325 | |
326 | Returns \c true if the asynchronous computation has been paused with the |
327 | pause() function; otherwise returns \c false. |
328 | |
329 | Be aware that the computation may still be running even though this |
330 | function returns \c true. See setPaused() for more details. To check |
331 | if pause actually took effect, use isSuspended() instead. |
332 | |
333 | \sa setSuspended(), toggleSuspended(), isSuspended() |
334 | */ |
335 | |
336 | bool QFutureWatcherBase::isPaused() const |
337 | { |
338 | QT_WARNING_PUSH |
339 | QT_WARNING_DISABLE_DEPRECATED |
340 | return futureInterface().isPaused(); |
341 | QT_WARNING_POP |
342 | } |
343 | #endif // QT_DEPRECATED_SINCE(6, 0) |
344 | |
345 | /*! \fn template <typename T> bool QFutureWatcher<T>::isSuspending() const |
346 | |
347 | \since 6.0 |
348 | |
349 | Returns \c true if the asynchronous computation has been suspended with the |
350 | suspend() function, but the work is not yet suspended, and computation is still |
351 | running. Returns \c false otherwise. |
352 | |
353 | To check if suspension is actually in effect, use isSuspended() instead. |
354 | |
355 | \sa setSuspended(), toggleSuspended(), isSuspended() |
356 | */ |
357 | bool QFutureWatcherBase::isSuspending() const |
358 | { |
359 | return futureInterface().isSuspending(); |
360 | } |
361 | |
362 | /*! \fn template <typename T> bool QFutureWatcher<T>::isSuspended() const |
363 | |
364 | \since 6.0 |
365 | |
366 | Returns \c true if a suspension of the asynchronous computation has been |
367 | requested, and it is in effect, meaning that no more results or progress |
368 | changes are expected. |
369 | |
370 | \sa suspended(), setSuspended(), isSuspending() |
371 | */ |
372 | bool QFutureWatcherBase::isSuspended() const |
373 | { |
374 | return futureInterface().isSuspended(); |
375 | } |
376 | |
377 | /*! \fn template <typename T> void QFutureWatcher<T>::waitForFinished() |
378 | |
379 | Waits for the asynchronous computation to finish (including cancel()ed |
380 | computations), i.e. until isFinished() returns \c true. |
381 | */ |
382 | void QFutureWatcherBase::waitForFinished() |
383 | { |
384 | futureInterface().waitForFinished(); |
385 | } |
386 | |
387 | bool QFutureWatcherBase::event(QEvent *event) |
388 | { |
389 | Q_D(QFutureWatcherBase); |
390 | if (event->type() == QEvent::FutureCallOut) { |
391 | QFutureCallOutEvent *callOutEvent = static_cast<QFutureCallOutEvent *>(event); |
392 | d->sendCallOutEvent(event: callOutEvent); |
393 | return true; |
394 | } |
395 | return QObject::event(event); |
396 | } |
397 | |
398 | /*! \fn template <typename T> void QFutureWatcher<T>::setPendingResultsLimit(int limit) |
399 | |
400 | The setPendingResultsLimit() provides throttling control. When the number |
401 | of pending resultReadyAt() or resultsReadyAt() signals exceeds the |
402 | \a limit, the computation represented by the future will be throttled |
403 | automatically. The computation will resume once the number of pending |
404 | signals drops below the \a limit. |
405 | */ |
406 | void QFutureWatcherBase::setPendingResultsLimit(int limit) |
407 | { |
408 | Q_D(QFutureWatcherBase); |
409 | d->maximumPendingResultsReady = limit; |
410 | } |
411 | |
412 | void QFutureWatcherBase::connectNotify(const QMetaMethod &signal) |
413 | { |
414 | Q_D(QFutureWatcherBase); |
415 | static const QMetaMethod resultReadyAtSignal = QMetaMethod::fromSignal(signal: &QFutureWatcherBase::resultReadyAt); |
416 | if (signal == resultReadyAtSignal) |
417 | d->resultAtConnected.ref(); |
418 | #ifndef QT_NO_DEBUG |
419 | static const QMetaMethod finishedSignal = QMetaMethod::fromSignal(signal: &QFutureWatcherBase::finished); |
420 | if (signal == finishedSignal) { |
421 | if (futureInterface().isRunning()) { |
422 | //connections should be established before calling stFuture to avoid race. |
423 | // (The future could finish before the connection is made.) |
424 | qWarning(msg: "QFutureWatcher::connect: connecting after calling setFuture() is likely to produce race" ); |
425 | } |
426 | } |
427 | #endif |
428 | } |
429 | |
430 | void QFutureWatcherBase::disconnectNotify(const QMetaMethod &signal) |
431 | { |
432 | Q_D(QFutureWatcherBase); |
433 | static const QMetaMethod resultReadyAtSignal = QMetaMethod::fromSignal(signal: &QFutureWatcherBase::resultReadyAt); |
434 | if (signal == resultReadyAtSignal) |
435 | d->resultAtConnected.deref(); |
436 | } |
437 | |
438 | /*! |
439 | \internal |
440 | */ |
441 | QFutureWatcherBasePrivate::QFutureWatcherBasePrivate() |
442 | : maximumPendingResultsReady(QThread::idealThreadCount() * 2), |
443 | resultAtConnected(0) |
444 | { } |
445 | |
446 | /*! |
447 | \internal |
448 | */ |
449 | void QFutureWatcherBase::connectOutputInterface() |
450 | { |
451 | futureInterface().d->connectOutputInterface(iface: d_func()); |
452 | } |
453 | |
454 | /*! |
455 | \internal |
456 | */ |
457 | void QFutureWatcherBase::disconnectOutputInterface(bool pendingAssignment) |
458 | { |
459 | if (pendingAssignment) { |
460 | Q_D(QFutureWatcherBase); |
461 | d->pendingResultsReady.storeRelaxed(newValue: 0); |
462 | } |
463 | |
464 | futureInterface().d->disconnectOutputInterface(iface: d_func()); |
465 | } |
466 | |
467 | void QFutureWatcherBasePrivate::postCallOutEvent(const QFutureCallOutEvent &callOutEvent) |
468 | { |
469 | Q_Q(QFutureWatcherBase); |
470 | |
471 | if (callOutEvent.callOutType == QFutureCallOutEvent::ResultsReady) { |
472 | if (pendingResultsReady.fetchAndAddRelaxed(valueToAdd: 1) >= maximumPendingResultsReady) |
473 | q->futureInterface().d->internal_setThrottled(enable: true); |
474 | } |
475 | |
476 | QCoreApplication::postEvent(receiver: q, event: callOutEvent.clone()); |
477 | } |
478 | |
479 | void QFutureWatcherBasePrivate::callOutInterfaceDisconnected() |
480 | { |
481 | QCoreApplication::removePostedEvents(receiver: q_func(), eventType: QEvent::FutureCallOut); |
482 | } |
483 | |
484 | void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event) |
485 | { |
486 | Q_Q(QFutureWatcherBase); |
487 | |
488 | switch (event->callOutType) { |
489 | case QFutureCallOutEvent::Started: |
490 | emit q->started(); |
491 | break; |
492 | case QFutureCallOutEvent::Finished: |
493 | emit q->finished(); |
494 | break; |
495 | case QFutureCallOutEvent::Canceled: |
496 | pendingResultsReady.storeRelaxed(newValue: 0); |
497 | emit q->canceled(); |
498 | break; |
499 | case QFutureCallOutEvent::Suspending: |
500 | if (q->futureInterface().isCanceled()) |
501 | break; |
502 | emit q->suspending(); |
503 | #if QT_DEPRECATED_SINCE(6, 0) |
504 | QT_WARNING_PUSH |
505 | QT_WARNING_DISABLE_DEPRECATED |
506 | emit q->paused(); |
507 | QT_WARNING_POP |
508 | #endif |
509 | break; |
510 | case QFutureCallOutEvent::Suspended: |
511 | if (q->futureInterface().isCanceled()) |
512 | break; |
513 | emit q->suspended(); |
514 | break; |
515 | case QFutureCallOutEvent::Resumed: |
516 | if (q->futureInterface().isCanceled()) |
517 | break; |
518 | emit q->resumed(); |
519 | break; |
520 | case QFutureCallOutEvent::ResultsReady: { |
521 | if (q->futureInterface().isCanceled()) |
522 | break; |
523 | |
524 | if (pendingResultsReady.fetchAndAddRelaxed(valueToAdd: -1) <= maximumPendingResultsReady) |
525 | q->futureInterface().setThrottled(false); |
526 | |
527 | const int beginIndex = event->index1; |
528 | const int endIndex = event->index2; |
529 | |
530 | emit q->resultsReadyAt(beginIndex, endIndex); |
531 | |
532 | if (resultAtConnected.loadRelaxed() <= 0) |
533 | break; |
534 | |
535 | for (int i = beginIndex; i < endIndex; ++i) |
536 | emit q->resultReadyAt(resultIndex: i); |
537 | |
538 | } break; |
539 | case QFutureCallOutEvent::Progress: |
540 | if (q->futureInterface().isCanceled()) |
541 | break; |
542 | |
543 | emit q->progressValueChanged(progressValue: event->index1); |
544 | if (!event->text.isNull()) // ### |
545 | emit q->progressTextChanged(progressText: event->text); |
546 | break; |
547 | case QFutureCallOutEvent::ProgressRange: |
548 | emit q->progressRangeChanged(minimum: event->index1, maximum: event->index2); |
549 | break; |
550 | default: break; |
551 | } |
552 | } |
553 | |
554 | |
555 | /*! \fn template <typename T> const T &QFutureWatcher<T>::result() const |
556 | |
557 | Returns the first result in the future(). If the result is not immediately |
558 | available, this function will block and wait for the result to become |
559 | available. This is a convenience method for calling resultAt(0). |
560 | |
561 | \sa resultAt() |
562 | */ |
563 | |
564 | /*! \fn template <typename T> const T &QFutureWatcher<T>::resultAt(int index) const |
565 | |
566 | Returns the result at \a index in the future(). If the result is not |
567 | immediately available, this function will block and wait for the result to |
568 | become available. |
569 | |
570 | \sa result() |
571 | */ |
572 | |
573 | /*! \fn template <typename T> void QFutureWatcher<T>::setFuture(const QFuture<T> &future) |
574 | |
575 | Starts watching the given \a future. |
576 | |
577 | If \a future has already started, the watcher will initially emit signals |
578 | that bring their listeners up to date about the future's state. The |
579 | following signals will, if applicable, be emitted in the given order: |
580 | started(), progressRangeChanged(), progressValueChanged(), |
581 | progressTextChanged(), resultsReadyAt(), resultReadyAt(), suspending(), |
582 | suspended(), canceled(), and finished(). Of these, resultsReadyAt() and |
583 | resultReadyAt() may be emitted several times to cover all available |
584 | results. progressValueChanged() and progressTextChanged() will only be |
585 | emitted once for the latest available progress value and text. |
586 | |
587 | To avoid a race condition, it is important to call this function |
588 | \e after doing the connections. |
589 | */ |
590 | |
591 | /*! \fn template <typename T> QFuture<T> QFutureWatcher<T>::future() const |
592 | |
593 | Returns the watched future. |
594 | */ |
595 | |
596 | /*! \fn template <typename T> void QFutureWatcher<T>::started() |
597 | |
598 | This signal is emitted when this QFutureWatcher starts watching the future |
599 | set with setFuture(). |
600 | */ |
601 | |
602 | /*! |
603 | \fn template <typename T> void QFutureWatcher<T>::finished() |
604 | This signal is emitted when the watched future finishes. |
605 | */ |
606 | |
607 | /*! |
608 | \fn template <typename T> void QFutureWatcher<T>::canceled() |
609 | This signal is emitted if the watched future is canceled. |
610 | */ |
611 | |
612 | /*! \fn template <typename T> void QFutureWatcher<T>::suspending() |
613 | |
614 | \since 6.0 |
615 | |
616 | This signal is emitted when the state of the watched future is |
617 | set to suspended. |
618 | |
619 | \note This signal only informs that suspension has been requested. It |
620 | doesn't indicate that all background operations are stopped. Signals |
621 | for computations that were in progress at the moment of suspending will |
622 | still be delivered. To be informed when suspension actually |
623 | took effect, use the suspended() signal. |
624 | |
625 | \sa setSuspended(), suspend(), suspended() |
626 | */ |
627 | |
628 | #if QT_DEPRECATED_SINCE(6, 0) |
629 | /*! \fn template <typename T> void QFutureWatcher<T>::paused() |
630 | |
631 | \deprecated [6.0] Use suspending() instead. |
632 | |
633 | This signal is emitted when the state of the watched future is |
634 | set to paused. |
635 | |
636 | \note This signal only informs that pause has been requested. It |
637 | doesn't indicate that all background operations are stopped. Signals |
638 | for computations that were in progress at the moment of pausing will |
639 | still be delivered. To to be informed when pause() actually |
640 | took effect, use the suspended() signal. |
641 | |
642 | \sa setSuspended(), suspend(), suspended() |
643 | */ |
644 | #endif // QT_DEPRECATED_SINCE(6, 0) |
645 | |
646 | /*! \fn template <typename T> void QFutureWatcher<T>::suspended() |
647 | |
648 | \since 6.0 |
649 | |
650 | This signal is emitted when suspend() took effect, meaning that there are |
651 | no more running computations. After receiving this signal no more result |
652 | ready or progress reporting signals are expected. |
653 | |
654 | \sa setSuspended(), suspend(), suspended() |
655 | */ |
656 | |
657 | /*! \fn template <typename T> void QFutureWatcher<T>::resumed() |
658 | This signal is emitted when the watched future is resumed. |
659 | */ |
660 | |
661 | /*! |
662 | \fn template <typename T> void QFutureWatcher<T>::progressRangeChanged(int minimum, int maximum) |
663 | |
664 | The progress range for the watched future has changed to \a minimum and |
665 | \a maximum |
666 | */ |
667 | |
668 | /*! |
669 | \fn template <typename T> void QFutureWatcher<T>::progressValueChanged(int progressValue) |
670 | |
671 | This signal is emitted when the watched future reports progress, |
672 | \a progressValue gives the current progress. In order to avoid overloading |
673 | the GUI event loop, QFutureWatcher limits the progress signal emission |
674 | rate. This means that listeners connected to this slot might not get all |
675 | progress reports the future makes. The last progress update (where |
676 | \a progressValue equals the maximum value) will always be delivered. |
677 | */ |
678 | |
679 | /*! \fn template <typename T> void QFutureWatcher<T>::progressTextChanged(const QString &progressText) |
680 | |
681 | This signal is emitted when the watched future reports textual progress |
682 | information, \a progressText. |
683 | */ |
684 | |
685 | /*! |
686 | \fn template <typename T> void QFutureWatcher<T>::resultReadyAt(int index) |
687 | |
688 | This signal is emitted when the watched future reports a ready result at |
689 | \a index. If the future reports multiple results, the index will indicate |
690 | which one it is. Results can be reported out-of-order. To get the result, |
691 | call resultAt(index); |
692 | */ |
693 | |
694 | /*! |
695 | \fn template <typename T> void QFutureWatcher<T>::resultsReadyAt(int beginIndex, int endIndex); |
696 | |
697 | This signal is emitted when the watched future reports ready results. |
698 | The results are indexed from \a beginIndex to \a endIndex. |
699 | |
700 | */ |
701 | |
702 | QT_END_NAMESPACE |
703 | |
704 | #include "moc_qfuturewatcher.cpp" |
705 | |