What UI Framework Does Amnezia-Client Use?
Amnezia-Client uses Qt Quick (QML) as its UI framework, implementing all visual interfaces in declarative .qml files that bind to C++ backend controllers via Qt’s signal/slot mechanism.
The Amnezia VPN client (amnezia-vpn/amnezia-client) delivers a unified, native-grade user experience across Windows, macOS, Linux, Android, and iOS by building its entire graphical layer on top of the Qt framework. Rather than using web-based technologies or platform-specific UI kits, the project relies on Qt’s QML (Qt Meta Language) module to define responsive layouts and controls that compile to native code on every supported platform.
The UI Framework: Qt Quick and QML
The application’s interface is constructed entirely within the Qt Quick ecosystem. QML files import standard Qt modules such as QtQuick, QtQuick.Controls, and QtQuick.Layouts to define windows, buttons, navigation flows, and animations. This approach allows the Amnezia team to maintain a single declarative UI codebase while Qt’s underlying C++ engine handles rendering and platform abstraction.
Evidence from the Source Code
The entry point for the UI is located at client/ui/qml/main2.qml, which begins with explicit imports of Qt Quick modules:
import QtQuick
import QtQuick.Window
import QtQuick.Controls
Additional screens follow the same pattern. Files such as client/ui/qml/Pages2/PageStart.qml and client/ui/qml/Pages2/PageSettingsServersList.qml import QtQuick.Controls and QtQuick.Layouts to construct settings panels and server lists using Qt’s standardized control library. This confirms that Amnezia-client uses Qt Quick/QML for every visual element rather than native widgets or HTML-based rendering.
C++ and QML Integration
The C++ backend exposes business logic to the QML layer through Qt’s context property system. In client/main.cpp, the application initializes a QQmlApplicationEngine and registers controller instances—such as SettingsController and PageController—as context properties. This architecture allows QML components to invoke C++ methods and listen for signals using direct property bindings.
Key Implementation Files
Understanding the framework requires examining specific source files that bridge the declarative UI and imperative backend:
client/ui/qml/main2.qml— The root QML window that bootstraps the entire interface, imports all necessary Qt Quick modules, and hosts the primary navigation stack.client/ui/qml/Pages2/— Directory containing individual screen definitions (e.g.,PageStart.qml,PageSettingsServersList.qml) built with Qt Quick Controls 2.client/main.cpp— Application entry point that instantiatesQQmlApplicationEngine, exposes C++ controllers to QML viaQQmlContext::setContextProperty(), and loads the main QML file.service/src/qtservice.cpp— Platform-agnostic service handler that manages the application lifecycle and integrates with the QML UI through Qt’s event loop.service/src/qtservice_win.cpp— Windows-specific implementation demonstrating how Qt abstracts platform services while the UI remains consistent QML code.
How the QML UI is Structured
The project organizes its interface into modular QML components. The Pages2 directory houses discrete views for setup wizards, server configuration, and settings, each defined as reusable QML types. main2.qml orchestrates these pages using Qt Quick layout containers and establishes Connections objects to listen for C++ signal emissions. This modular structure ensures that UI updates in one file do not cascade into breaking changes across the entire application.
Connecting C++ Logic to the UI
The framework enables bidirectional communication between the Qt Quick frontend and the C++ backend. Below is a simplified example reflecting the pattern found in client/main.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "core/controllers/settingscontroller.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
// Expose C++ controller to QML
SettingsController settingsController;
engine.rootContext()->setContextProperty("SettingsController", &settingsController);
engine.load(QUrl(QStringLiteral("qrc:/client/ui/qml/main2.qml")));
return app.exec();
}
In the corresponding QML, buttons and input fields bind directly to SettingsController properties and invoke its slots:
import QtQuick
import QtQuick.Controls
Button {
text: qsTr("Save Settings")
onClicked: SettingsController.saveConfiguration()
}
Cross-Platform Architecture
Because Amnezia-client uses Qt as its foundation, the same QML files render natively across desktop and mobile without modification. Platform-specific adaptations—such as system tray behavior on Windows or background service handling on Android—are isolated in files like qtservice.cpp and qtservice_win.cpp. The UI layer remains pure Qt Quick, compiling to native graphics APIs (OpenGL, Vulkan, Metal, or Direct3D) depending on the target operating system.
Summary
- Amnezia-Client builds its interface with Qt Quick (QML), not Electron or native OS-specific toolkits.
- The UI is defined in
.qmlfiles underclient/ui/qml/, importing modules likeQtQuickandQtQuick.Controls. - C++ controllers communicate with the QML frontend via
QQmlContextproperties and Qt’s signal/slot mechanism. - Files such as
client/main.cppandservice/src/qtservice.cppmanage the integration between the Qt event loop and platform-specific services. - This architecture provides a single codebase that compiles to native performance on Windows, macOS, Linux, Android, and iOS.
Frequently Asked Questions
Does Amnezia-client use Electron or Qt?
Amnezia-client uses Qt, specifically the Qt Quick (QML) module. The repository contains no Electron or Chromium-dependent code; instead, all UI components are declared in .qml files processed by the native Qt rendering engine.
Why did Amnezia choose QML over native UI frameworks?
QML offers a declarative syntax that allows the development team to define complex, animated interfaces with less code than imperative UI toolkits. Because Qt compiles QML to native graphics calls, Amnezia achieves the performance benefits of native development while maintaining one unified codebase for all platforms.
How does the C++ backend communicate with the QML UI?
The application exposes C++ objects—such as SettingsController and PageController—to QML using QQmlContext::setContextProperty(). This makes the objects available as global properties in QML, allowing the UI to invoke C++ slots and react to C++ signals through standard Qt connections.
Is the Amnezia UI native on both mobile and desktop devices?
Yes. Although the source code uses QML, Qt compiles these declarative descriptions into native platform shaders and controls. The result is a native look and feel on Android and iOS (using appropriate styles) and native windowing on desktop operating systems, all from the same client/ui/qml source files.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →