Logo
3 min read
← All Insights

Software Architecture · Qt Framework

Software architecture with the Qt framework

Qt is the framework of choice for industrial desktop and embedded applications. But "using Qt" and "mastering Qt architecture" are two different things.

Most teams use Qt as a widget toolkit. That is like using a Swiss army knife only as a bottle opener. Qt is an architecture framework: signals/slots, property system, Model/View, plugin system, QML engine. The architecture decisions of the first two weeks determine the next five years of maintenance effort.

We have built and inherited Qt projects over the last 15 years. The well-structured ones were still extensible after 5 years. The poorly structured ones were practically unmaintainable after 2 years — at identical codebase size.

The Qt architecture layers

Qt is organised in layers. Whoever ignores these layers builds monolithic applications that break at every point.

Layer 1: Core

QObject, signals/slots, event loop, property system. This is the foundation. Every class deriving from QObject gets meta-object information, automatic memory management via parent-child hierarchies and thread-safe signal connections. Architecturally this means: all of your communication can run loosely coupled — if you allow it.

Layer 2: Data

QAbstractItemModel, proxy models, SQL back-ends. The Model/View system is Qt's strongest and most underestimated architecture component. Used correctly, it separates data logic completely from presentation. Used incorrectly — or ignored — data processing ends up in UI code.

Layer 3: UI

QML versus Widgets — the central architecture decision. Both technologies have legitimate uses. The choice determines build system, team composition and long-term maintainability. Hybrid approaches are possible but increase complexity considerably.

Layer 4: Integration

IPC, serial interfaces, networking, plugins. Qt ships modules for all of it. The architecture decision: do you use Qt's abstractions or your own? Qt's modules are well tested but create a dependency on the Qt ecosystem. Your own abstractions are more portable but have to be maintained.

QML vs Widgets — the architecture decision

Widgets: stable, mature, C++-native, runs on minimal hardware. Choose Widgets for: medical devices (IEC 62304), defence HMIs, classic desktop applications. Widgets are predictable — and in regulated environments predictability matters more than aesthetics.

QML: modern, GPU-accelerated, responsive, easier for designers. Choose QML for: automotive dashboards, consumer kiosks, data-rich UIs with animations. QML requires a clean C++/QML boundary — otherwise the application becomes unmaintainable.

Hybrid: possible, but complex. A C++ back-end with a QML front-end is the sweet spot for new projects. What matters is the clear separation: C++ provides data and logic, QML presents.

// C++ back-end: expose the data model
class SensorModel : public QAbstractListModel {
    Q_OBJECT
    Q_PROPERTY(int count READ count NOTIFY countChanged)
public:
    enum Roles { ValueRole = Qt::UserRole + 1, TimestampRole };
    int rowCount(const QModelIndex&) const override;
    QVariant data(const QModelIndex&, int role) const override;
signals:
    void countChanged();
};
// QML front-end: presentation
import QtQuick 2.15
ListView {
    model: sensorModel
    delegate: Row {
        Text { text: model.value }
        Text { text: model.timestamp }
    }
}
The architecture decision between QML and Widgets does not determine the look — it determines the next 5 years of maintenance cost.

Typical architecture mistakes

  • God-object MainWindow: Everything in one class. 5,000 lines of MainWindow.cpp. Not testable, not extensible, not migratable.
  • Business logic in the UI layer: Calculations in button-click handlers. Consequence: no unit tests possible, no migration to another UI technology.
  • Direct SQL in QML: Database queries without a model layer. Every schema change breaks the UI.
  • Ignoring the event loop: Blocking calls in the main thread. Result: frozen UI, frustrated users, unstable application.
  • No dependency injection: Everything hard-wired. Testing requires the whole application, components are not replaceable.

Example from practice

A medical-device manufacturer ran a Qt5 Widgets application with 200,000 lines of code. The MainWindow contained 40% of the business logic. Migrating to Qt6 took 8 months instead of the estimated 3 — because the architecture had no layers. The logic was so tightly interwoven with the UI that every API change touched dozens of files.

Trade-offs

  • Licence cost: Qt Commercial costs EUR 5,000-20,000 per developer per year. Open source (LGPL/GPL) is possible but requires careful licence compliance.
  • QML overhead: The QML engine needs memory and GPU. On embedded systems with 256 MB RAM that matters. Widgets are lighter.
  • C++/QML bridge: The learning curve is steep. Teams need 2-3 months until the architecture is clean. Early mistakes take their revenge later.
  • Vendor lock-in: Qt is a comprehensive ecosystem. The more Qt modules you use, the harder a switch becomes. That is a deliberate decision.

Further reading

AI in safety-critical systems (German)

How AI works in regulated environments — IEC 62304, ISO 26262 and reality.

AI projects after the PoC (German)

Why 80% of AI projects fail after the proof of concept.

From the book: Chapter 7 — 70/30 as an architecture principle (PDF)

Sample chapter from "Forget Prompts. The 70/30 AI System" — free, no e-mail required.

Your AlpiType team
Landsberg am Lech · alpitype.de

Related articles

KI nutzen, ohne Daten in die Cloud zu schicken

On-premise KI: Wie Systeme vollständig lokal betrieben werden.

Sind Ihre Daten überhaupt für KI nutzbar?

Datenqualität prüfen, bevor Sie in KI investieren.

Was KI in einem realen Industrieprojekt kostet

Konkrete Zahlen, Phasen und ROI aus realen Projekten.

Not sure if this applies to your case?

We can check your setup in 2 weeks and tell you if AI is feasible.

Request feasibility audit →

Talk to an engineer

No sales team. You talk directly with one of our software architects about your specific problem. 30 minutes. Response within 24 hours.

Email: info@alpitype.com

LinkedIn: AlpiType

Anton Lytvynenko

Anton Lytvynenko

CEO, AlpiType

Our Story →