Masaüstü ve gömülü Qt uygulamalarında kullanıcı tercihlerinin (son açılan pencere konumu, seçilen seri port, dil seçeneği veya koyu tema tercihi) uygulama kapatılıp açıldığında korunması profesyonel bir kullanıcı deneyiminin vazgeçilmezidir. Qt Framework’ün platformlar arası bir yapılandırma yöneticisi sunan sınıfı QSettings kullanımı, geliştiricileri her işletim sistemi için ayrı dosya formatı ve dizin yapısı tasarlama zahmetinden kurtarır.
Bu rehberde; QSettings mimarisini, platform bazlı varsayılan depolama mekanizmalarını (Linux’ta ~/.config, Windows’ta Registry, macOS’ta plist), taşınabilir INI dosyası oluşturmayı, pencere geometrisini saklamayı ve grup hiyerarşisi oluşturmayı öğreneceğiz.
QSettings Platform Depolama Stratejisi
Varsayılan olarak QSettings(organization, application) şeklinde başlatıldığında, hedef işletim sisteminin yerel yapılandırma standardına otomatik uyum sağlar:
| İşletim Sistemi | Varsayılan Depolama Biçimi | Depolama Konumu |
|---|---|---|
| Linux / Unix | INI / Metin Dosyası | ~/.config/<Organization>/<Application>.conf |
| Windows | Windows Registry | HKEYCURRENTUSER\Software\<Organization>\<Application> |
| macOS | XML / Property List (.plist) | ~/Library/Preferences/com.<org>.<app>.plist |
| Taşınabilir / Her Yerde | Özel INI Dosyası | Uygulama dizini veya özel dosya yolu |
Temel Kullanım: Değer Yazma ve Okuma
QSettings, anahtar-değer (Key-Value) çiftleri mantığıyla çalışır ve değerleri QVariant türünde saklar:
#include <QCoreApplication>
#include <QSettings>
#include <QDebug>
void saveSettings() {
// Şirket ve Uygulama adı üzerinden nesne oluşturulur
QSettings settings("MyCompany", "SerialMonitorApp");
// Değerleri kaydet (String, int, bool, double vb.)
settings.setValue("network/port", 8080);
settings.setValue("network/host", "192.168.1.10");
settings.setValue("ui/dark_mode", true);
settings.setValue("app/recent_file", "/home/user/log.txt");
// Değişiklikleri diske hemen yazmaya zorla (isteğe bağlı)
settings.sync();
}
void loadSettings() {
QSettings settings("MyCompany", "SerialMonitorApp");
// Değeri oku (Varsayılan değer desteği: defaultValue)
int port = settings.value("network/port", 80).toInt();
QString host = settings.value("network/host", "127.0.0.1").toString();
bool darkMode = settings.value("ui/dark_mode", false).toBool();
qDebug() << "Okunan Ayarlar -> Host:" << host << "Port:" << port << "Koyu Tema:" << darkMode;
}
Önemli İpucu:
settings.value("key", defaultValue)fonksiyonundaki ikinci parametre çok kritiktir. Eğer ayar dosyası henüz oluşmamışsa veya anahtar silinmişse, uygulamanız çökmeden belirttiğiniz güvenli varsayılan değerle başlar.
Pencere Konumu ve Boyutunu Saklamak (saveGeometry & restoreGeometry)
Bir pencerenin ekran üzerindeki boyutunu, konumunu ve tam ekran (maximized) olup olmadığını manuel int değerlerle saklamak çok zahmetlidir. Qt bunun için doğrudan QByteArray formatında mükemmel iki fonksiyon sunar:
#include <QMainWindow>
#include <QSettings>
#include <QCloseEvent>
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
readWindowSettings();
}
protected:
void closeEvent(QCloseEvent *event) override {
writeWindowSettings();
event->accept();
}
private:
void writeWindowSettings() {
QSettings settings("MyCompany", "SerialMonitorApp");
settings.beginGroup("MainWindow");
// Pencere geometrisini (boyut + konum) ve durumunu (araç çubukları, dock pencereleri) sakla
settings.setValue("geometry", saveGeometry());
settings.setValue("windowState", saveState());
settings.endGroup();
}
void readWindowSettings() {
QSettings settings("MyCompany", "SerialMonitorApp");
settings.beginGroup("MainWindow");
// Kaydedilmiş geometriyi geri yükle
const QByteArray geometry = settings.value("geometry", QByteArray()).toByteArray();
if (!geometry.isEmpty()) {
restoreGeometry(geometry);
}
const QByteArray state = settings.value("windowState", QByteArray()).toByteArray();
if (!state.isEmpty()) {
restoreState(state);
}
settings.endGroup();
}
};
Taşınabilir (Portable) INI Dosyaları Kullanmak
Uygulamanızın Windows Registry’yi kirletmesini istemiyorsanız veya USB bellekten çalışan taşınabilir bir uygulama geliştiriyorsanız, platformdan bağımsız olarak doğrudan .ini formatını zorlayabilirsiniz:
#include <QSettings>
#include <QCoreApplication>
// Uygulama ile aynı dizinde 'config.ini' dosyası oluştur
QString configPath = QCoreApplication::applicationDirPath() + "/config.ini";
QSettings settings(configPath, QSettings::IniFormat);
settings.setIniCodec("UTF-8"); // Türkçe karakter desteği için kritik!
settings.setValue("Database/Name", "production_db");
settings.setValue("Database/User", "ahmet");
Gruplar ile Hiyerarşik Yapı Kurmak (beginGroup / endGroup)
Karmaşık projelerde yüzlerce ayar olduğunda, anahtarları kategorize etmek için gruplar kullanılır:
QSettings settings("config.ini", QSettings::IniFormat);
settings.beginGroup("SerialPort");
settings.setValue("BaudRate", 115200);
settings.setValue("DataBits", 8);
settings.setValue("Parity", "None");
settings.endGroup();
settings.beginGroup("MQTT");
settings.setValue("BrokerUrl", "mqtt.ahakan.com");
settings.setValue("KeepAlive", 60);
settings.endGroup();
Üretilen config.ini dosyası son derece düzenli görünür:
[SerialPort]
BaudRate=115200
DataBits=8
Parity=None
[MQTT]
BrokerUrl=mqtt.ahakan.com
KeepAlive=60
QVariant Listeleri ve Dizileri Saklamak (beginWriteArray)
Kullanıcının son açtığı son 5 dosya listesini (Recent Files) saklamak için beginWriteArray kullanılır:
QStringList recentFiles = {"/tmp/a.log", "/tmp/b.log", "/tmp/c.log"};
QSettings settings("config.ini", QSettings::IniFormat);
settings.beginWriteArray("RecentFiles");
for (int i = 0; i < recentFiles.size(); ++i) {
settings.setArrayIndex(i);
settings.setValue("path", recentFiles.at(i));
}
settings.endArray();
Özet
Qt uygulamalarınızda kullanıcı deneyimini zenginleştirmek için QSettings sınıfını tercih edin. Otomatik işletim sistemi entegrasyonu, saveGeometry ile kusursuz pencere hafızası ve UTF-8 destekli INI formatı sayesinde yapılandırma yönetimi güvenli ve zahmetsiz hale gelir.