Critique my C++/Qt Task Framework - Is this a bad design?
Hey r/QtFramework,
I've implemented a small framework for running asynchronous/background tasks in my Qt application and I'm looking for some feedback on the design. I'm a bit concerned I might be doing something that's considered an anti-pattern or has hidden dangers.
My main goals were:
* Run jobs in a background thread pool.
* Get signals back on the main thread for completion (success/failure).
* Some tasks could be fire & forget.
* Keep the tasks mockable for unit tests.
Because of the mocking requirement, I steered clear of `QtConcurrent::run` and created my own `QRunnable`\-based system.
# The Design
The core of the framework is an abstract base class that inherits from both `QObject` and `QRunnable`:
`AbstractTask.hpp`
#include <QObject>
#include <QRunnable>
#include <QString>
#include <QVariant>
class AbstractTask : public QObject, public QRunnable {
Q_OBJECT
public:
explicit AbstractTask(QObject* parent = nullptr) {
// Per-task memory management.
setAutoDelete(false);
}
// The main execution wrapper, handles signals and exceptions.
void run() override final {
emit started();
try {
if (execute()) {
emit finished(true, m_errorMessage, m_result);
} else {
emit finished(false, m_errorMessage, m_result);
}
} catch (const std::exception& e) {
m_errorMessage = e.what();
emit finished(false, m_errorMessage, m_result);
}
}
signals:
void started();
void finished(bool success, const QString& errorMessage, const QVariant& result);
protected:
// Concrete tasks implement their logic here.
virtual bool execute() = 0;
// Helpers for subclasses
void setResult(const QVariant& result) { m_result = result; }
void setError(const QString& errorMessage) { m_errorMessage = errorMessage; }
private:
QString m_errorMessage;
QVariant m_result;
};
A concrete task looks like this:
class MyConcreteTask : public AbstractTask {
/* ... constructor, etc. ... */
protected:
bool execute() override {
// Do background work...
if (/* success */) {
setResult(42);
return true;
} else {
setError("Something went wrong");
return false;
}
}
};
And this is how I use it:
void SomeClass::startMyTask() {
auto* task = new MyConcreteTask();
// Connect signals to handle results on the main thread
connect(task, &MyConcreteTask::finished, this, &SomeClass::handleTaskFinished);
// IMPORTANT: Manage the object's lifetime
connect(task, &MyConcreteTask::finished, task, &QObject::deleteLater);
// Run it
QThreadPool::globalInstance()->start(task);
}
# My Specific Concerns:
1. **Inheriting** `QObject` **and** `QRunnable`: This seems to be the standard way to get signals from a `QRunnable`, but is it a good practice?
2. **Memory Management**: I'm explicitly calling `setAutoDelete(false)`. My understanding is that this is necessary because the default auto-deletion can cause a crash if the task finishes and is deleted before its signals are processed. By connecting `finished` to `deleteLater`, I'm ensuring the task is safely deleted on its "home" thread (the main thread) after all signals are emitted. Is this logic sound?
3. `QtConcurrent` **Alternative**: I know `QtConcurrent` is often recommended. My main issue with it is the difficulty in mocking the free function `QtConcurrent::run`. My `AbstractTask` interface is easy to mock in tests. Is there a modern `QtConcurrent` pattern that's more test-friendly that I'm missing?
4. **General "Code Smell"**: Does this whole approach feel right to you? Or
Hey r/QtFramework,
I've implemented a small framework for running asynchronous/background tasks in my Qt application and I'm looking for some feedback on the design. I'm a bit concerned I might be doing something that's considered an anti-pattern or has hidden dangers.
My main goals were:
* Run jobs in a background thread pool.
* Get signals back on the main thread for completion (success/failure).
* Some tasks could be fire & forget.
* Keep the tasks mockable for unit tests.
Because of the mocking requirement, I steered clear of `QtConcurrent::run` and created my own `QRunnable`\-based system.
# The Design
The core of the framework is an abstract base class that inherits from both `QObject` and `QRunnable`:
`AbstractTask.hpp`
#include <QObject>
#include <QRunnable>
#include <QString>
#include <QVariant>
class AbstractTask : public QObject, public QRunnable {
Q_OBJECT
public:
explicit AbstractTask(QObject* parent = nullptr) {
// Per-task memory management.
setAutoDelete(false);
}
// The main execution wrapper, handles signals and exceptions.
void run() override final {
emit started();
try {
if (execute()) {
emit finished(true, m_errorMessage, m_result);
} else {
emit finished(false, m_errorMessage, m_result);
}
} catch (const std::exception& e) {
m_errorMessage = e.what();
emit finished(false, m_errorMessage, m_result);
}
}
signals:
void started();
void finished(bool success, const QString& errorMessage, const QVariant& result);
protected:
// Concrete tasks implement their logic here.
virtual bool execute() = 0;
// Helpers for subclasses
void setResult(const QVariant& result) { m_result = result; }
void setError(const QString& errorMessage) { m_errorMessage = errorMessage; }
private:
QString m_errorMessage;
QVariant m_result;
};
A concrete task looks like this:
class MyConcreteTask : public AbstractTask {
/* ... constructor, etc. ... */
protected:
bool execute() override {
// Do background work...
if (/* success */) {
setResult(42);
return true;
} else {
setError("Something went wrong");
return false;
}
}
};
And this is how I use it:
void SomeClass::startMyTask() {
auto* task = new MyConcreteTask();
// Connect signals to handle results on the main thread
connect(task, &MyConcreteTask::finished, this, &SomeClass::handleTaskFinished);
// IMPORTANT: Manage the object's lifetime
connect(task, &MyConcreteTask::finished, task, &QObject::deleteLater);
// Run it
QThreadPool::globalInstance()->start(task);
}
# My Specific Concerns:
1. **Inheriting** `QObject` **and** `QRunnable`: This seems to be the standard way to get signals from a `QRunnable`, but is it a good practice?
2. **Memory Management**: I'm explicitly calling `setAutoDelete(false)`. My understanding is that this is necessary because the default auto-deletion can cause a crash if the task finishes and is deleted before its signals are processed. By connecting `finished` to `deleteLater`, I'm ensuring the task is safely deleted on its "home" thread (the main thread) after all signals are emitted. Is this logic sound?
3. `QtConcurrent` **Alternative**: I know `QtConcurrent` is often recommended. My main issue with it is the difficulty in mocking the free function `QtConcurrent::run`. My `AbstractTask` interface is easy to mock in tests. Is there a modern `QtConcurrent` pattern that's more test-friendly that I'm missing?
4. **General "Code Smell"**: Does this whole approach feel right to you? Or
does it seem like a clunky, old-fashioned way of doing things in modern Qt (I'm on Qt 5.15)?
# Known Improvements
1. Type-safety of `AbstractTask` result and error messages. I think we can make a templated `AbstractTaskWithResult` which inherits from `AbstractTask`, move result form `AbstractTask` to templated `AbstractTaskWithResult`.
2. Error could be a `enum class` and string pair instead of a string.
I'd really appreciate any insights, critiques, or suggestions for improvement. Thanks!
https://redd.it/1ntbt54
@qt_reddit
# Known Improvements
1. Type-safety of `AbstractTask` result and error messages. I think we can make a templated `AbstractTaskWithResult` which inherits from `AbstractTask`, move result form `AbstractTask` to templated `AbstractTaskWithResult`.
2. Error could be a `enum class` and string pair instead of a string.
I'd really appreciate any insights, critiques, or suggestions for improvement. Thanks!
https://redd.it/1ntbt54
@qt_reddit
Reddit
From the QtFramework community on Reddit
Explore this post and more from the QtFramework community
Qt Jenny 1.0 Released (Integrate Android JNI objects directly with Qt)
https://www.qt.io/blog/qt-jenny-1.0-released
https://redd.it/1ntknyw
@qt_reddit
https://www.qt.io/blog/qt-jenny-1.0-released
https://redd.it/1ntknyw
@qt_reddit
www.qt.io
Qt Jenny 1.0 Released
Java/Android JNI glue/proxy Qt code generator
Dual-Language General-Purpose Self-Hosted Visual Language and new Textual Programming Language for Applications
https://arxiv.org/abs/2509.20426
https://redd.it/1nulk2h
@qt_reddit
https://arxiv.org/abs/2509.20426
https://redd.it/1nulk2h
@qt_reddit
arXiv.org
Dual-Language General-Purpose Self-Hosted Visual Language and new...
Most visual programming languages (VPLs) are domain-specific, with few general-purpose VPLs like Programming Without Coding Technology (PWCT). These general-purpose VPLs are developed using...
I've made an unofficial KDE Kirigami subreddit; feel free to submit articles and questions related to Kirigami
https://www.reddit.com/r/KDE_Kirigami/
https://redd.it/1nusqj0
@qt_reddit
https://www.reddit.com/r/KDE_Kirigami/
https://redd.it/1nusqj0
@qt_reddit
Reddit
r/KDE_Kirigami
The unofficial subreddit for KDE's Kirigami UI Framework
Easiest way to build a Mac executable from a Windows machine
Hi everyone!
Everything is in the title.
I researched the best way to build a Mac executable for my QT app (standard C++ with a couple of libraries in QT Creator).
It seems that the easiest way would be to pay for a virtual environment, but is there an easier/ cheaper way to build a Mac executable file?
I'm also new to the world of virtual env so I'd take any advice you may have if this is indeed the best way to proceed.
Cheers!
https://redd.it/1nuza5c
@qt_reddit
Hi everyone!
Everything is in the title.
I researched the best way to build a Mac executable for my QT app (standard C++ with a couple of libraries in QT Creator).
It seems that the easiest way would be to pay for a virtual environment, but is there an easier/ cheaper way to build a Mac executable file?
I'm also new to the world of virtual env so I'd take any advice you may have if this is indeed the best way to proceed.
Cheers!
https://redd.it/1nuza5c
@qt_reddit
Reddit
From the QtFramework community on Reddit
Explore this post and more from the QtFramework community
Emulating key pressed on tests
Code is simple:
void MoveDownOneLine() {
Qutepart::Qutepart qpart(nullptr, "one\ntwo\nthree\nfour");
QTest::keyClick(&qpart, Qt::KeyDown, Qt::AltModifier);
QCOMPARE(qpart.toPlainText(), QString("two\none\nthree\nfour"));
QTest::keyClick(&qpart, Qt::KeyDown, Qt::AltModifier);
QCOMPARE(qpart.toPlainText(), QString("two\nthree\none\nfour"));
QTest::keyClick(&qpart, Qt::KeyDown, Qt::AltModifier);
QCOMPARE(qpart.toPlainText(), QString("two\nthree\nfour\none"));
QTest::keyClick(&qpart, Qt::KeyDown, Qt::AltModifier);
QCOMPARE(qpart.toPlainText(), QString("two\nthree\nfour\none"));
qpart.undo();
QCOMPARE(qpart.toPlainText(), QString("two\nthree\none\nfour"));
qpart.undo();
QCOMPARE(qpart.toPlainText(), QString("two\none\nthree\nfour"));
}
That key combination is trapped to a QShortcut, which calls a slot, which moves the lines. This works only for the first shortcut. Things I tested:
1. QTest::keyDown/keyUP.
2. Adding timouts after each event
3. QApplication::processEvents();
4. QTest::qSleep(300);
I have no idea why the events are not passed to the widget. Doing the same scenario on "wet", in real app, works as expected.
What should my next step be?
https://redd.it/1nv74ba
@qt_reddit
Code is simple:
void MoveDownOneLine() {
Qutepart::Qutepart qpart(nullptr, "one\ntwo\nthree\nfour");
QTest::keyClick(&qpart, Qt::KeyDown, Qt::AltModifier);
QCOMPARE(qpart.toPlainText(), QString("two\none\nthree\nfour"));
QTest::keyClick(&qpart, Qt::KeyDown, Qt::AltModifier);
QCOMPARE(qpart.toPlainText(), QString("two\nthree\none\nfour"));
QTest::keyClick(&qpart, Qt::KeyDown, Qt::AltModifier);
QCOMPARE(qpart.toPlainText(), QString("two\nthree\nfour\none"));
QTest::keyClick(&qpart, Qt::KeyDown, Qt::AltModifier);
QCOMPARE(qpart.toPlainText(), QString("two\nthree\nfour\none"));
qpart.undo();
QCOMPARE(qpart.toPlainText(), QString("two\nthree\none\nfour"));
qpart.undo();
QCOMPARE(qpart.toPlainText(), QString("two\none\nthree\nfour"));
}
That key combination is trapped to a QShortcut, which calls a slot, which moves the lines. This works only for the first shortcut. Things I tested:
1. QTest::keyDown/keyUP.
2. Adding timouts after each event
3. QApplication::processEvents();
4. QTest::qSleep(300);
I have no idea why the events are not passed to the widget. Doing the same scenario on "wet", in real app, works as expected.
What should my next step be?
https://redd.it/1nv74ba
@qt_reddit
Reddit
From the QtFramework community on Reddit
Explore this post and more from the QtFramework community
GUI based user actions simulations automation and scheduler tool (free & open source)
https://redd.it/1nwoadv
@qt_reddit
https://redd.it/1nwoadv
@qt_reddit
QPlainTextEdit home/end on macOS
Hi all,
on Linux/Windows home/end will move by default to the start/end of the line. However - on macOS - this moves to the end/start of the document. Does QPlainTextEdit still implement this? Where can I see the implementation of this, in the sources?
(PS: I don't own a mac, otherwise this would be trivial)
https://redd.it/1nwsxb6
@qt_reddit
Hi all,
on Linux/Windows home/end will move by default to the start/end of the line. However - on macOS - this moves to the end/start of the document. Does QPlainTextEdit still implement this? Where can I see the implementation of this, in the sources?
(PS: I don't own a mac, otherwise this would be trivial)
https://redd.it/1nwsxb6
@qt_reddit
Reddit
From the QtFramework community on Reddit
Explore this post and more from the QtFramework community
Looking for Icon Suggestions for Project Hospital
Hello everyone! π
I'm currently focused on enhancing the UI of project hospital and I'm interested in adding some nice, clean, and modern icons, for aesthetics.
If you have any recommendations - perhaps from sites like Flaticon, Icons8, or other open-source resources - please post them here!
I am in the midst of what appears to be a finishing phase, so there's no need to worry when it comes time to use the icons. I will first take your input, and select or modify the selected icons for project hospital.
β³ I'm thinking of keeping this thread open for about a week before I modify the design - does that sound okay?
The update will be uploaded soon.
Thanks again to everyone - I really appreciate the help! π
https://redd.it/1nzdh8p
@qt_reddit
Hello everyone! π
I'm currently focused on enhancing the UI of project hospital and I'm interested in adding some nice, clean, and modern icons, for aesthetics.
If you have any recommendations - perhaps from sites like Flaticon, Icons8, or other open-source resources - please post them here!
I am in the midst of what appears to be a finishing phase, so there's no need to worry when it comes time to use the icons. I will first take your input, and select or modify the selected icons for project hospital.
β³ I'm thinking of keeping this thread open for about a week before I modify the design - does that sound okay?
The update will be uploaded soon.
Thanks again to everyone - I really appreciate the help! π
https://redd.it/1nzdh8p
@qt_reddit
Reddit
From the QtFramework community on Reddit
Explore this post and more from the QtFramework community
llama.qtcreator v2.0.0 released. Now with chat support.
I've released πππππ.πππππππππ v2.0.0 π
You can chat with a local AI from Qt Creator now!
You can install it by adding https://github.com/cristianadam/qtcreator-extension-registry/archive/refs/heads/main.tar.gz to Extensions > Repository URLs
https://preview.redd.it/icm564krfgtf1.jpg?width=2210&format=pjpg&auto=webp&s=22ffd9ce1428d65b138096a24ecaa8b84a62dfb3
https://redd.it/1nzdsk2
@qt_reddit
I've released πππππ.πππππππππ v2.0.0 π
You can chat with a local AI from Qt Creator now!
You can install it by adding https://github.com/cristianadam/qtcreator-extension-registry/archive/refs/heads/main.tar.gz to Extensions > Repository URLs
https://preview.redd.it/icm564krfgtf1.jpg?width=2210&format=pjpg&auto=webp&s=22ffd9ce1428d65b138096a24ecaa8b84a62dfb3
https://redd.it/1nzdsk2
@qt_reddit
GitHub
Release Release v2.0.0 Β· cristianadam/llama.qtcreator
This plugin has been compiled against Qt Creator 17.0.1.
This version adds Chat support.
New menu entry Tool > llama.cpp > New conversation
New llama.cpp Conversations View
New "ll"...
This version adds Chat support.
New menu entry Tool > llama.cpp > New conversation
New llama.cpp Conversations View
New "ll"...
Problem with adding resources in qml project
Hi everyone, I'm doing my second project with qt framework (this time is an Android application and it's my first time using qt creator). I'm using qml for the UI, but i'm having trouble with adding resources to the project, precisely i would add icons to the buttons that I have. I've follwed the tutorials that invece found on youtube, but they didn't work. The steps that I've follwed are:
1. Add a resources.qrc file
2. Add to the cmake the the addqmlresources module
3. Add a prefix to resources.qrc and add to it the icon's files (from the dialog of qt Creator I've seen that I'm copying the files from my FS to the project directory).
I saw that there is another way to add the resources to the cmake. I'didn't understand the way to reference to a resource in the qml file.
Thank you in advance
https://redd.it/1nzdckp
@qt_reddit
Hi everyone, I'm doing my second project with qt framework (this time is an Android application and it's my first time using qt creator). I'm using qml for the UI, but i'm having trouble with adding resources to the project, precisely i would add icons to the buttons that I have. I've follwed the tutorials that invece found on youtube, but they didn't work. The steps that I've follwed are:
1. Add a resources.qrc file
2. Add to the cmake the the addqmlresources module
3. Add a prefix to resources.qrc and add to it the icon's files (from the dialog of qt Creator I've seen that I'm copying the files from my FS to the project directory).
I saw that there is another way to add the resources to the cmake. I'didn't understand the way to reference to a resource in the qml file.
Thank you in advance
https://redd.it/1nzdckp
@qt_reddit
Reddit
From the QtFramework community on Reddit
Explore this post and more from the QtFramework community
My Own Qt Creator Plugin License(Qt Company GPL Exception 1.0)
I would like to create a plugin for Qt Creator, and I understand the term from Qt Company GPL Exception 1.0(https://github.com/qt-creator/qt-creator/blob/master/LICENSES/LICENSE.GPL3-EXCEPT)
Exception 2:
As a special exception, you have permission to combine this application
with Plugins licensed under the terms of your choice, to produce an
executable, and to copy and distribute the resulting executable under
the terms of your choice. However, the executable must be accompanied
by a prominent notice offering all users of the executable the entire
source code to this application, excluding the source code of the
independent modules, but including any changes you have made to this
application, under the terms of this license.
so could it mean the plugin that I build can be with my own proprietary license?
https://redd.it/1o09j33
@qt_reddit
I would like to create a plugin for Qt Creator, and I understand the term from Qt Company GPL Exception 1.0(https://github.com/qt-creator/qt-creator/blob/master/LICENSES/LICENSE.GPL3-EXCEPT)
Exception 2:
As a special exception, you have permission to combine this application
with Plugins licensed under the terms of your choice, to produce an
executable, and to copy and distribute the resulting executable under
the terms of your choice. However, the executable must be accompanied
by a prominent notice offering all users of the executable the entire
source code to this application, excluding the source code of the
independent modules, but including any changes you have made to this
application, under the terms of this license.
so could it mean the plugin that I build can be with my own proprietary license?
https://redd.it/1o09j33
@qt_reddit
GitHub
qt-creator/LICENSES/LICENSE.GPL3-EXCEPT at master Β· qt-creator/qt-creator
A cross-platform Qt IDE. Contribute to qt-creator/qt-creator development by creating an account on GitHub.
How to design Pipe and Valve system
Hi Guys,
What is best of way to design Pipe and Valve complex system?
I created Pipe and Valve components with Canvas, I used them to create simple system but for complex system, it becomes very complex to manage. Each Pipe and valve have some properties to backend if its on or off.
https://redd.it/1o0dwxh
@qt_reddit
Hi Guys,
What is best of way to design Pipe and Valve complex system?
I created Pipe and Valve components with Canvas, I used them to create simple system but for complex system, it becomes very complex to manage. Each Pipe and valve have some properties to backend if its on or off.
https://redd.it/1o0dwxh
@qt_reddit
Reddit
From the QtFramework community on Reddit
Explore this post and more from the QtFramework community
Issues with numpy and Python3; Trying to do a graph in Qt5 in a pi4 model b but I get this error.
Last night or rather this morning Ive tried re installing numpy in 3 different ways, removed libraries and re installed them I even installed 3 different types of imports that can graph but they all link to numpys error
https://preview.redd.it/4t6fcqxa5qtf1.jpg?width=3194&format=pjpg&auto=webp&s=925c7cd7c2c17c92a91023d6833c134ad2038eb9
https://redd.it/1o0l87r
@qt_reddit
Last night or rather this morning Ive tried re installing numpy in 3 different ways, removed libraries and re installed them I even installed 3 different types of imports that can graph but they all link to numpys error
https://preview.redd.it/4t6fcqxa5qtf1.jpg?width=3194&format=pjpg&auto=webp&s=925c7cd7c2c17c92a91023d6833c134ad2038eb9
https://redd.it/1o0l87r
@qt_reddit
