A Qt-based unified settings library with file monitoring and cross-application synchronization for Uni desktop environment.
- Unified Configuration Management: Single API for both application-specific and system-wide settings
- Automatic Change Detection: File-system watcher with debounced change detection for real-time synchronization
- Qt Native: Built on QSettings with full support for Qt data types and QVariant
- Hierarchical Organization: Group-based key organization for clean configuration structure
- Thread-Safe Singleton: Mutex-protected singleton pattern for system-wide settings access
- QML Integration: SystemSettings provides Q_INVOKABLE methods for QML access
- Macro-Based Property System: Declarative property definitions with automatic signal emission
- Cross-Application Reading: Read settings from other applications within the same scope
- Qt6 Core
- C++20 compiler
- CMake 3.16+
mkdir build && cd build
cmake ..
cmake --build .
sudo cmake --install . --prefix=/usrThe library installs headers to /usr/include/unisettings/ and the shared library to the system library directory.
The main settings class supporting both system-wide and application-specific configurations.
#include <unisettings.h>
// Application-specific settings
auto *settings = new UniSettings("myapp", this);
// Write values
settings->setValue("window/width", 800);
settings->setValue("theme", "dark"); // specific to app
// Read with defaults
int width = settings->value("window/width", 1024).toInt();
QString theme = settings->value("theme", "light").toString();
// Force synchronization if smth goes wrong
settings->sync();// Access system singleton
auto *systemSettings = UniSettings::instance();
systemSettings->setValue("global/theme", "dark");
// Read system settings from app scope
QVariant theme = settings->systemValue("global/theme", "light"); // fallback system theme is lightsettings->beginGroup("window");
settings->setValue("width", 1920); // Stored as "window/width"
settings->setValue("height", 1080); // Stored as "window/height"
settings->endGroup();
QString currentGroup = settings->group();// Local value changes
connect(settings, &UniSettings::valueChanged,
[](const QString &key, const QVariant &value) {
qDebug() << "Changed:" << key << "=" << value;
});
// External file changes (other processes)
connect(settings, &UniSettings::externalValueChanged,
[](const QString &appName, const QString &key, const QVariant &value) {
qDebug() << appName << "setting" << key << "changed to" << value;
});// Read another app's settings
QVariant otherValue = settings->appValue("otherapp", "some/key", "fallback");
// Check key existence
if (settings->contains("theme")) {
...
}
// List all keys
QStringList keys = settings->allKeys();
// Remove keys
settings->remove("obsolete/setting");
// Clear all settings
settings->clear();QML-friendly singleton wrapper around UniSettings for system-wide configuration.
#include <systemsettings.h>
auto *sys = SystemSettings::instance();
// Basic operations
sys->setValue("theme", "dark");
QVariant theme = sys->value("theme", "light");
// Read application settings from system scope
QVariant appTheme = sys->appValue("myapp", "theme", "dark");
// Signals
connect(sys, &SystemSettings::settingChanged,
[](const QString &key, const QVariant &value) {
qDebug() << "System setting changed:" << key;
});The macro system provides declarative property definitions with automatic signal handling [file:2].
#include <unisettings_macros.h>
// Define settings class
UNISETTINGS_CLASS(AppSettings, "myapp")
// Property with explicit key
UNISETTINGS_PROPERTY(QString, theme, "ui/theme", "light")
// Property with auto-generated key (uses property name)
UNISETTINGS_PROPERTY_AUTO(int, windowWidth, 1024)
// Grouped property
UNISETTINGS_PROPERTY_GROUP(bool, maximized, "window", "maximized", false)
UNISETTINGS_END()// Implement loading and change handling
UNISETTINGS_IMPL_BEGIN(AppSettings)
UNISETTINGS_LOAD_PROPERTY(theme)
UNISETTINGS_LOAD_PROPERTY(windowWidth)
UNISETTINGS_LOAD_PROPERTY(maximized)
UNISETTINGS_IMPL_CHANGE_BEGIN(AppSettings)
UNISETTINGS_HANDLE_CHANGE("ui/theme", theme)
UNISETTINGS_HANDLE_CHANGE("windowWidth", windowWidth)
UNISETTINGS_HANDLE_CHANGE("maximized", maximized)
UNISETTINGS_IMPL_END()auto *appSettings = new AppSettings(this);
// Access as properties
QString currentTheme = appSettings->theme();
appSettings->setTheme("dark");
// Listen for changes
connect(appSettings, &AppSettings::themeChanged, []() {
qDebug() << "Theme changed!";
});
// Access underlying UniSettings object
UniSettings *raw = appSettings->settings();Settings are stored as INI files in the XDG config directory:
- System settings:
~/.config/unisettings/system.conf - Application settings:
~/.config/unisettings/<appname>.conf
The library uses QFileSystemWatcher to monitor configuration files and directories. Changes are debounced with a 100ms timer to prevent excessive signal emission during bulk updates. An internal cache tracks values to detect actual changes versus file-system noise.
Two scopes are supported:
- SystemScope: Desktop environment settings (system.conf)
- ApplicationScope: Per-application settings (.conf)
The system scope singleton watches all .conf files in the settings directory and emits externalValueChanged signals when any application's settings change.
| Method | Description |
|---|---|
value(key, default) |
Read setting with default fallback |
setValue(key, value) |
Write setting and emit signals |
contains(key) |
Check if key exists |
remove(key) |
Delete a setting |
allKeys() |
List all keys in current scope |
clear() |
Remove all settings |
sync() |
Force write to disk |
beginGroup(prefix) |
Start hierarchical group |
endGroup() |
End current group |
group() |
Get current group path |
systemValue(key, default) |
Read from system scope |
appValue(app, key, default) |
Read from another app |
applicationName() |
Get application name |
scope() |
Get current scope |
valueChanged(QString key, QVariant value)- Emitted on local changesexternalValueChanged(QString appName, QString key, QVariant value)- Emitted on file changes
MIT