Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
src_corelib_thread_qfuture.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
3
5QFuture<QString> future = ...;
6
8for (i = future.constBegin(); i != future.constEnd(); ++i)
9 cout << qPrintable(*i) << endl;
11
12
14QFuture<QString> future;
15...
16QFutureIterator<QString> i(future);
17while (i.hasNext())
18 QString s = i.next();
20
21
23QFutureIterator<QString> i(future);
24i.toBack();
25while (i.hasPrevious())
26 QString s = i.previous();
28
30using NetworkReply = std::variant<QByteArray, QNetworkReply::NetworkError>;
31
33using IOResult = std::variant<QString, IOError>;
35
37QFuture<IOResult> future = QtConcurrent::run([url] {
38 ...
40}).then([](NetworkReply reply) {
41 if (auto error = std::get_if<QNetworkReply::NetworkError>(&reply))
43
44 auto data = std::get_if<QByteArray>(&reply);
45 // try to write *data and return IOError::FailedToWrite on failure
46 ...
47});
48
49auto result = future.result();
50if (auto filePath = std::get_if<QString>(&result)) {
51 // do something with *filePath
52else
53 // process the error
55
57QFuture<int> future = ...;
58 future.then([](QFuture<int> f) {
59 try {
60 ...
61 auto result = f.result();
62 ...
63 } catch (QException &e) {
64 // handle the exception
65 }
66 }).then(...);
68
70QFuture<int> future = ...;
71auto continuation = future.then([](int res1){ ... }).then([](int res2){ ... })...
72...
73// future throws an exception
74try {
75 auto result = continuation.result();
76} catch (QException &e) {
77 // handle the exception
78}
80
82QFuture<int> future = ...;
83auto resultFuture = future.then([](int res) {
84 ...
85 throw Error();
86 ...
87}).onFailed([](const Error &e) {
88 // Handle exceptions of type Error
89 ...
90 return -1;
91}).onFailed([] {
92 // Handle all other types of errors
93 ...
94 return -1;
95});
96
97auto result = resultFuture.result(); // result is -1
99
101QFuture<int> future = ...;
102future.then([](int res) {
103 ...
104 throw std::runtime_error("message");
105 ...
106}).onFailed([](const std::exception &e) {
107 // This handler will be invoked
108}).onFailed([](const std::runtime_error &e) {
109 // This handler won't be invoked, because of the handler above.
110});
112
114QFuture<int> future = ...;
115auto resultFuture = future.then([](int res) {
116 ...
117 throw Error("message");
118 ...
119}).onFailed([](const std::exception &e) {
120 // Won't be invoked
121}).onFailed([](const QException &e) {
122 // Won't be invoked
123});
124
125try {
126 auto result = resultFuture.result();
127} catch(...) {
128 // Handle the exception
129}
131
133class Object : public QObject
134{
136 ...
137signals:
138 void noArgSignal();
139 void singleArgSignal(int value);
140 void multipleArgs(int value1, double value2, const QString &value3);
141};
143
146QFuture<void> voidFuture = QtFuture::connect(&object, &Object::noArgSignal);
147QFuture<int> intFuture = QtFuture::connect(&object, &Object::singleArgSignal);
148
149using Args = std::tuple<int, double, QString>;
150QFuture<Args> tupleFuture = QtFuture::connect(&object, &Object::multipleArgs)
152
154QtFuture::connect(&object, &Object::singleArgSignal).then([](int value) {
155 // do something with the value
156});
158
160QtFuture::connect(&object, &Object::singleArgSignal).then(QtFuture::Launch::Async, [](int value) {
161 // this will run in a new thread
162});
164
166QtFuture::connect(&object, &Object::singleArgSignal).then([](int value) {
167 ...
168 throw std::exception();
169 ...
170}).onFailed([](const std::exception &e) {
171 // handle the exception
172}).onFailed([] {
173 // handle other exceptions
174});
176
178QFuture<int> testFuture = ...;
179auto resultFuture = testFuture.then([](int res) {
180 // Block 1
181}).onCanceled([] {
182 // Block 2
183}).onFailed([] {
184 // Block 3
185}).then([] {
186 // Block 4
187}).onFailed([] {
188 // Block 5
189}).onCanceled([] {
190 // Block 6
191});
193
195QFuture<int> testFuture = ...;
196auto resultFuture = testFuture.then([](int res) {
197 // Block 1
198}).onFailed([] {
199 // Block 3
200}).then([] {
201 // Block 4
202}).onFailed([] {
203 // Block 5
204}).onCanceled([] {
205 // Block 6
206});
208
210// somewhere in the main thread
211auto future = QtConcurrent::run([] {
212 // This will run in a separate thread
213 ...
214}).then(this, [] {
215 // Update UI elements
216});
218
220auto future = QtConcurrent::run([] {
221 ...
222}).then(this, [] {
223 // Update UI elements
224}).then([] {
225 // This will also run in the main thread
226});
228
230// somewhere in the main thread
231auto future = QtConcurrent::run([] {
232 // This will run in a separate thread
233 ...
234 throw std::exception();
235}).onFailed(this, [] {
236 // Update UI elements
237});
239
241QObject *context = ...;
242auto future = cachedResultsReady ? QtFuture::makeReadyValueFuture(result)
243 : QtConcurrent::run([] { /* compute result */});
244auto continuation = future.then(context, [] (Result result) {
245 // Runs in the context's thread
246}).then([] {
247 // May or may not run in the context's thread
248});
250
252QFuture<int> testFuture = ...;
253auto resultFuture = testFuture.then([](int res) {
254 // Block 1
255 ...
256 return 1;
257}).then([](int res) {
258 // Block 2
259 ...
260 return 2;
261}).onCanceled([] {
262 // Block 3
263 ...
264 return -1;
265});
267
269QList<QFuture<int>> inputFutures {...};
270
271// whenAll has type QFuture<QList<QFuture<int>>>
272auto whenAll = QtFuture::whenAll(inputFutures.begin(), inputFutures.end());
273
274// whenAllVector has type QFuture<std::vector<QFuture<int>>>
275auto whenAllVector =
276 QtFuture::whenAll<std::vector<QFuture<int>>>(inputFutures.begin(), inputFutures.end());
278
280QList<QFuture<int>> inputFutures {...};
281
282QtFuture::whenAll(inputFutures.begin(), inputFutures.end())
283 .then([](const QList<QFuture<int>> &results) {
284 for (auto future : results) {
285 if (future.isCanceled())
286 // handle the cancellation (possibly due to an exception)
287 else
288 // do something with the result
289 }
290 });
292
294
295QFuture<int> intFuture = ...;
296QFuture<QString> stringFuture = ...;
297QFuture<void> voidFuture = ...;
298
299using FuturesVariant = std::variant<QFuture<int>, QFuture<QString>, QFuture<void>>;
300
301// whenAll has type QFuture<QList<FuturesVariant>>
302auto whenAll = QtFuture::whenAll(intFuture, stringFuture, voidFuture);
303
304// whenAllVector has type QFuture<std::vector<FuturesVariant>>
305auto whenAllVector =
306 QtFuture::whenAll<std::vector<FuturesVariant>>(intFuture, stringFuture, voidFuture);
307
309
311QFuture<int> intFuture = ...;
312QFuture<QString> stringFuture = ...;
313QFuture<void> voidFuture = ...;
314
315using FuturesVariant = std::variant<QFuture<int>, QFuture<QString>, QFuture<void>>;
316
317QtFuture::whenAll(intFuture, stringFuture, voidFuture)
318 .then([](const QList<FuturesVariant> &results) {
319 ...
320 for (auto result : results)
321 {
322 // assuming handleResult() is overloaded based on the QFuture type
323 std::visit([](auto &&future) { handleResult(future); }, result);
324 }
325 ...
326 });
328
330QList<QFuture<int>> inputFutures = ...;
331
332QtFuture::whenAny(inputFutures.begin(), inputFutures.end())
333 .then([](const QtFuture::WhenAnyResult<int> &result) {
334 qsizetype index = result.index;
335 QFuture<int> future = result.future;
336 // ...
337 });
339
341QFuture<int> intFuture = ...;
342QFuture<QString> stringFuture = ...;
343QFuture<void> voidFuture = ...;
344
345using FuturesVariant = std::variant<QFuture<int>, QFuture<QString>, QFuture<void>>;
346
347QtFuture::whenAny(intFuture, stringFuture, voidFuture).then([](const FuturesVariant &result) {
348 ...
349 // assuming handleResult() is overloaded based on the QFuture type
350 std::visit([](auto &&future) { handleResult(future); }, result);
351 ...
352});
354
356
357QFuture<QFuture<int>> outerFuture = ...;
358QFuture<int> unwrappedFuture = outerFuture.unwrap();
359
361
363
364auto downloadImages = [] (const QUrl &url) {
365 QList<QImage> images;
366 ...
367 return images;
368};
369
370auto processImages = [](const QList<QImage> &images) {
371 return QtConcurrent::mappedReduced(images, scale, reduceImages);
372}
373
374auto show = [](const QImage &image) { ... };
375
376auto future = QtConcurrent::run(downloadImages, url)
377 .then(processImages)
378 .unwrap()
379 .then(show);
381
383
384QFuture<QFuture<QFuture<int>>>> outerFuture;
385QFuture<int> unwrappedFuture = outerFuture.unwrap();
386
388
390QPromise<int> p;
391
392QFuture<int> f1 = p.future();
393f1.then([](int) { qDebug("first"); });
394
395QFuture<int> f2 = p.future();
396f2.then([](int) { qDebug("second"); });
397
398p.start();
399p.addResult(42);
400p.finish();
402
404const std::vector<int> values{1, 2, 3};
407
409auto f = QtFuture::makeReadyRangeFuture({1, 2, 3});
411
413const int count = f.resultCount(); // count == 3
414const auto results = f.results(); // results == { 1, 2, 3 }
416
418auto f = QtFuture::makeReadyValueFuture(std::make_unique<int>(42));
419...
420const int result = *f.takeResult(); // result == 42
422
425...
426const bool started = f.isStarted(); // started == true
427const bool running = f.isRunning(); // running == false
428const bool finished = f.isFinished(); // finished == true
430
432QObject *context = ...;
433auto future = ...;
434auto continuation = future.then(context, [context](Result result) {
435 // ...
436 }).onCanceled([context = QPointer(context)] {
437 if (!context)
438 return; // context was destroyed already
439 // handle cancellation
440 });
441
Definition main.cpp:8
\inmodule QtCore
Definition qexception.h:22
\inmodule QtGui
Definition qimage.h:37
Definition qlist.h:75
\inmodule QtCore
Definition qobject.h:103
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
\inmodule QtCore
Definition qurl.h:94
QTCONCURRENT_RUN_NODISCARD auto run(QThreadPool *pool, Function &&f, Args &&...args)
QFuture< ResultType > mappedReduced(QThreadPool *pool, Sequence &&sequence, MapFunctor &&map, ReduceFunctor &&reduce, ReduceOptions options=ReduceOptions(UnorderedReduce|SequentialReduce))
QFuture< OutputSequence > whenAll(InputIt first, InputIt last)
Definition qfuture.h:460
Q_CORE_EXPORT QFuture< void > makeReadyVoidFuture()
static QFuture< std::decay_t< T > > makeReadyValueFuture(T &&value)
static QFuture< ContainedType< Container > > makeReadyRangeFuture(Container &&container)
static QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QFuture< WhenAnyResult< typename QtPrivate::Future< ValueType >::type > > whenAny(InputIt first, InputIt last)
Definition qfuture.h:498
Definition image.cpp:4
static void * context
DBusConnection const char DBusError * error
static Q_CONSTINIT QBasicAtomicInt running
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
void uint64_t uint64_t uint64_t value2
#define qDebug
[1]
Definition qlogging.h:164
GLenum GLsizei GLsizei GLint * values
[15]
GLuint index
[2]
GLenum GLenum GLsizei count
GLuint object
[3]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat GLfloat f
GLdouble s
[6]
Definition qopenglext.h:235
GLuint res
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
GLenum GLenum GLenum GLenum GLenum scale
#define qPrintable(string)
Definition qstring.h:1531
#define Q_OBJECT
ptrdiff_t qsizetype
Definition qtypes.h:165
view show()
[18] //! [19]
QList< QImage > images
[6]
QUrl url("example.com")
[constructor-url-reference]
std::variant< QString, IOError > IOResult
std::variant< QByteArray, QNetworkReply::NetworkError > NetworkReply
[2]
QFuture< QString > future
[0]
QFuture< QString >::const_iterator i
@ FailedToWrite
@ FailedToRead
QNetworkReply * reply