# How UI Components Are Managed in the Amnezia VPN Client: Qt/QML Architecture Explained

> Understand how Amnezia VPN client manages UI components using a Qt QML architecture. Explore C++ controllers, context properties, and declarative page loading. Learn more now.

- Repository: [Amnezia VPN/amnezia-client](https://github.com/amnezia-vpn/amnezia-client)
- Tags: architecture
- Published: 2026-07-28

---

**The Amnezia VPN client manages UI components through a hybrid architecture where the `AmneziaApplication` C++ class instantiates a `QQmlApplicationEngine` to load declarative QML pages, while specialized C++ controllers exposed as context properties handle focus management, navigation, and business logic.**

The Amnezia VPN client repository (`amnezia-vpn/amnezia-client`) implements a clean separation between presentation and logic. How UI components are managed in Amnezia VPN client centers on Qt Quick/QML for the visual layer, with C++ controller classes bridging the gap between the declarative frontend and the VPN backend services.

## Application Bootstrap and Engine Initialization

The UI lifecycle begins in the `AmneziaApplication` class, which acts as the central coordinator for the Qt Quick runtime.

### AmneziaApplication Class

In [`client/amneziaApplication.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/amneziaApplication.cpp), the `AmneziaApplication` constructor creates the `QQmlApplicationEngine` instance that powers the entire interface. This engine manages the component tree, resource loading, and QML context properties.

```cpp
// client/amneziaApplication.cpp - simplified excerpt
void AmneziaApplication::init()
{
    m_engine = new QQmlApplicationEngine;
    
    // Register controller objects with the root context
    QQmlContext *ctx = m_engine->rootContext();
    ctx->setContextProperty("focusController", new FocusController(m_engine));
    
    // Load the root QML document
    m_engine->load(QUrl(QStringLiteral("qrc:/client/ui/qml/main2.qml")));
}

```

According to the Amnezia VPN source code, the engine initialization sequence ensures that controller objects are instantiated and exposed to QML **before** the root component loads, allowing QML files to access these objects immediately upon creation.

### Root QML Entry Point

The engine loads `client/ui/qml/main2.qml`, which serves as the application's root window. This file establishes the fundamental visual structure, typically containing a `StackView` for page-based navigation and the global synchronization engine.

```qml
// client/ui/qml/main2.qml - conceptual structure
import QtQuick 2.15
import QtQuick.Controls 2.15

ApplicationWindow {
    id: root
    visible: true
    
    StackView {
        id: stackView
        anchors.fill: parent
        initialItem: "Pages2/PageHome.qml"
    }
}

```

## Declarative UI Component Organization

The QML source tree follows a strict organizational pattern that separates pages, reusable controls, and styling logic.

### Page Components (Pages2)

Individual screens reside in `client/ui/qml/Pages2/`, with each major feature implemented as a distinct QML file. Key pages include:

- **`PageHome.qml`** – Main dashboard displaying connection status
- **`PageSettings.qml`** – Configuration and preferences interface  
- **`PageSetupWizardStart.qml`** – Initial VPN setup flow

These components are standard QML `Page` types that declare their own visual hierarchy while inheriting shared styling from the global theme module.

### Shared Controls and Styling

Reusable UI elements are centralized under `client/ui/qml/Controls2/`, preventing duplication across pages. The visual theme is defined in `client/ui/qml/Modules/Style/AmneziaStyle.qml`, which exports color palettes, font metrics, and spacing constants.

```qml
// client/ui/qml/Controls2/ButtonTextType.qml
import QtQuick 2.15
import "../Modules/Style"

Text {
    font.family: AmneziaStyle.fontFamily
    color: AmneziaStyle.primaryColor
    font.pixelSize: AmneziaStyle.textSizeMedium
}

```

This modular approach ensures consistent styling across the application; changes to `AmneziaStyle.qml` propagate automatically to all controls.

## C++ Controllers: Logic Bridge to QML

While the UI is declarative, complex interactions—particularly focus management and backend communication—are handled by C++ controllers instantiated by `AmneziaApplication`.

### FocusController Implementation

The `FocusController` class in [`client/ui/controllers/qml/focusController.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/ui/controllers/qml/focusController.cpp) demonstrates the controller pattern. As implemented in `amnezia-vpn/amnezia-client`, it connects to the `QQmlApplicationEngine::objectCreated` signal to locate the `defaultFocusItem` object by name and implements custom keyboard navigation logic.

```cpp
// client/ui/controllers/qml/focusController.cpp
FocusController::FocusController(QQmlApplicationEngine *engine, QObject *parent)
    : QObject(parent), m_engine(engine)
{
    connect(m_engine, &QQmlApplicationEngine::objectCreated,
            this, &FocusController::onObjectCreated);
}

void FocusController::onObjectCreated(QObject *object, const QUrl &url)
{
    // Locate default focus item by objectName
    if (QObject *focusItem = object->findChild<QObject*>("defaultFocusItem")) {
        // Initialize focus tracking for this page
    }
}

```

This controller exposes methods like `nextKeyTabItem()` and `nextKeyUpItem()` as QML-callable slots.

### Exposing Controllers to QML

Controllers are registered as context properties in `AmneziaApplication::init()`, making them accessible to any QML file loaded by the engine:

```cpp
ctx->setContextProperty("focusController", m_focusController);

```

QML pages invoke these controller methods directly in response to user input:

```qml
// client/ui/qml/Pages2/PageHome.qml
Page {
    Keys.onTabPressed: focusController.nextKeyTabItem()
    Keys.onBackPressed: focusController.nextKeyUpItem()
    
    // Component definition...
}

```

## Navigation and Dynamic Component Loading

Navigation follows a stack-based pattern managed by the `StackView` defined in `main2.qml`. Controllers can trigger navigation changes by emitting signals that QML handlers catch, or by invoking `QMetaObject::invokeMethod` on QML objects.

### StackView Page Management

New pages are pushed onto the stack declaratively:

```qml
// Within a page, navigating to settings
stackView.push("PageSettings.qml")

```

Or dynamically from C++:

```cpp
// Controller pushing a new page
QMetaObject::invokeMethod(rootObject, "pushPage",
                          Q_ARG(QVariant, QVariant::fromValue(QString("PageSettings.qml"))));

```

## Summary

- **Engine Ownership**: The `AmneziaApplication` class in [`client/amneziaApplication.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/amneziaApplication.cpp) creates and owns the `QQmlApplicationEngine`, loading `client/ui/qml/main2.qml` as the root component.
- **Component Organization**: UI pages reside in `client/ui/qml/Pages2/`, reusable controls in `client/ui/qml/Controls2/`, and global styling in `client/ui/qml/Modules/Style/AmneziaStyle.qml`.
- **Controller Pattern**: C++ controllers like `FocusController` ([`client/ui/controllers/qml/focusController.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/ui/controllers/qml/focusController.cpp)) are exposed as context properties to handle complex logic while keeping QML declarative.
- **Navigation**: The `StackView` in `main2.qml` manages page transitions, with pages pushed declaratively or via C++ to QML invocation.

## Frequently Asked Questions

### What is the entry point for the Amnezia VPN UI?

The entry point is `client/ui/qml/main2.qml`, which is loaded by the `QQmlApplicationEngine` instantiated in the `AmneziaApplication` class within [`client/amneziaApplication.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/amneziaApplication.cpp). This root QML file sets up the application window and the `StackView` that manages page navigation.

### How does the Amnezia VPN client handle keyboard navigation?

Keyboard navigation is managed by the `FocusController` class located in [`client/ui/controllers/qml/focusController.cpp`](https://github.com/amnezia-vpn/amnezia-client/blob/main/client/ui/controllers/qml/focusController.cpp). This C++ controller connects to the QML engine's `objectCreated` signal to track focus items by object name and exposes methods like `nextKeyTabItem()` that QML pages call in response to key events such as `Keys.onTabPressed`.

### Where are UI components defined in the Amnezia VPN client source code?

UI components are defined in three primary locations according to the repository structure: page-specific screens under `client/ui/qml/Pages2/` (e.g., `PageHome.qml`), reusable control elements under `client/ui/qml/Controls2/`, and the visual theme definition in `client/ui/qml/Modules/Style/AmneziaStyle.qml`.

### How is styling managed across the Amnezia VPN client UI?

Styling is centralized in the `AmneziaStyle.qml` module, which defines color constants, font families, and spacing values. All QML controls import this module, ensuring consistent theming across the application; modifying `AmneziaStyle.qml` immediately updates the appearance of all dependent components without requiring changes to individual control files.