Qt Task Tree module, coming soon in Qt 6.11, is designed to run various types of asynchronous tasks. One of these tasks may be a task that executes a function is a separate thread. This example demonstrates how to use QThreadFunctionTask in a task tree recipe and how to report the progress and final result of the computation.
<pre><code>
#include <QCoreApplication>
#include <QSingleTaskTreeRunner>
#include <QThreadFunction>
using namespace QtTaskTree;
static void threadTask(QPromise<QString> &promise, const QString &inputData)
{
const int stepsCount = inputData.size();
QString outputData;
for (int i = 0; i < stepsCount; ++i) {
outputData.prepend(inputData.at(i));
QThread::sleep(1);
const int progress = (i + 1) * 100.0 / stepsCount;
promise.setProgressValue(progress);
}
promise.addResult(outputData);
}
</code></pre>
The threadTask() function will execute in a separate thread. To report progress and result, the function takes a reference to a QPromise<QString> object. See Concurrent Run With Promise for more information on using QPromise in a function running in a separate thread. The threadTask() takes also an additional argument, the inputData string, which will be passed to the function as input. The threadTask() implementation is intentionally very simple – it reverses the input string and reports the reverted string as output. To simulate heavy computation, we add sleep call for 1 second in each iteration and report progress using promise.setProgressValue(progress). We provide the final result using promise.addResult(outputData)
<pre><code>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
const auto onSetup = [&app](QThreadFunction<QString> &task) {
task.setThreadFunctionData(threadTask, "REWARD");
QObject::connect(task.futureWatcher(), &QFutureWatcherBase::progressValueChanged,
&app, [](int value) { qDebug().noquote() << "Progress:" << value; });
};
const auto onDone = [](const QThreadFunction<QString> &task) {
qDebug().noquote() << "Result:" << task.result();
};
const Group recipe = { QThreadFunctionTask<QString>(onSetup, onDone, CallDoneFlag::OnSuccess) };
QSingleTaskTreeRunner taskTreeRunner;
taskTreeRunner.start(recipe, {}, [&app] { app.quit(); });
return app.exec();
}
</code></pre>
The main()function creates an instance of QCoreApplication – the task tree relies a the running event loop, so its presence is essential.
The QThreadFunction and its corresponding QThreadFunctionTask enables asynchronous execution of a function in a separate thread via task tree. When QThreadFunctionTask is executed, it automatically creates a new thread and runs the previously configured function in this thread. Once QThreadFunctionTask is started, the main thread immediately returns control to its event loop.
The < QString > template argument of QThreadFunction and QThreadFunctionTask indicates that the function running in a separate thread will provide a result of QString type.
The onSetup handler is called by the running task tree immediately after the QThreadFunction instance is created and before it’s executed. The handler is called from the main thread. We configure the threadTask() function to execute in a separate thread with the REWARD string passed as an argument. We also connect to the progressValueChanged() signal of the futureWatcher(), which reports the progress of the task running in the separate thread. Note that lambda body will also always executed in the main thread, so in this way we can safely update any possible GUI elements if the application uses them.The onDone handler is called by the running task tree immediately after the function completes its execution in a separate thread. This handler is also called from the main thread. The computation result is accessed via task.result().
The task tree recipe consists of a single asynchronous task: QThreadFunctionTask. Passing QThreadFunctionTask to the recipe instructs the running task tree to dynamically create an instance of QThreadFunction. The passed onSetup and onDone handlers are executed by the runningtask tree.
Finally, we start the task tree via QSingleTaskTreeRunner, passing the prepared recipe. The 3rd argument of the start() method takes a handler that is executed when the recipe completes. Inside this handler we quit the application.
After running this example, the output looks as follows:
Progress: 0
Progress: 16
Progress: 33
Progress: 50
Progress: 66
Progress: 83
Progress: 100
Result: DRAWER
<pre><code>
#include <QCoreApplication>
#include <QSingleTaskTreeRunner>
#include <QThreadFunction>
using namespace QtTaskTree;
static void threadTask(QPromise<QString> &promise, const QString &inputData)
{
const int stepsCount = inputData.size();
QString outputData;
for (int i = 0; i < stepsCount; ++i) {
outputData.prepend(inputData.at(i));
QThread::sleep(1);
const int progress = (i + 1) * 100.0 / stepsCount;
promise.setProgressValue(progress);
}
promise.addResult(outputData);
}
int main(int argc, char *argv[])
{
QCoreApplication app(argc,argv);
const auto onSetup = [&app](QThreadFunction<QString> &task) {
task.setThreadFunctionData(threadTask, "REWARD");
QObject::connect(task.futureWatcher(), &QFutureWatcherBase::progressValueChanged,
&app, [](int value) { qDebug().noquote() << "Progress:" << value; });
};
const auto onDone = [](const QThreadFunction<QString> &task) {
qDebug().noquote() << "Result:" << task.result();
};
const Group recipe = { QThreadFunctionTask<QString>(onSetup, onDone, CallDoneFlag::OnSuccess) };
QSingleTaskTreeRunner taskTreeRunner;
taskTreeRunner.start(recipe, {}, [&app] { app.quit(); });
return app.exec();
}
</code></pre>
Go Back to The Blog

Glass-Spider Limited
Landscape House
Baldonnell Business Park
Dublin 22 D22P3K7, Ireland
Register Number: 697326
EU VAT: IE3771710PH
e-mail: info [at] glass-spider [dot] io
Copyright © 2026 Glass-Spider Limited