Осваиваю тут QT 5 и сразу проблема, как хранить настройки приложения. Приложение гибридное логика на C++, интерфейс на QML. Для самой QT есть QSettings, для QML есть Settings. Все это здорово конечно, но хотелось бы все настройки иметь в одном месте, а не в двух. Так же хотелось бы чтобы если изменяют некий чекбокс в qml к примеру, то он менял соответствующую настройку и я мог ее прочитать на C++ и наоборот.
Этого можно добиться, простым путем: обернуть QSettings в свой класс и выставить его в QML через rootContext()->setContextProperty или вообще не оборачивать, а выставить как есть - но это уже детали.
Но при таком подходе, QML настройки из него конечно прочитает, но не узнает, если вдруг они изменились, можно подписать на сигнал изменения конечно, но это опять куча ручной работы. Также на каждое изменение настройки в QML придется писать обработчики из серии:
onXChanged: { settings.setValue("main.x", main.x); }
QML-й Settings умеет автоматически сохранять подцепленные к нему свойства, т.е. как в примере из доки:
import QtQuick.Window 2.1
import Qt.labs.settings 1.0
Window {
id: window
width: 800
height: 600
Settings {
property alias x: window.x
property alias y: window.y
property alias width: window.width
property alias height: window.height
}
}
В QML прописали что хотим сохранять и все само сохраняется при изменениях.
В связи с этим посмотрел исходники QML-го Settings, не вся реализация там есть, но основная идея вроде понятна.
Набросал тестовый пример: settings.h
#ifndef SETTINGS_H
#define SETTINGS_H
#include <QObject>
#include <QVariant>
#include <QDebug>
class Settings: public QObject
{
Q_OBJECT
Q_PROPERTY(QVariant test READ getTest WRITE setTest NOTIFY TestChanged)
public:
Settings(QObject *parent = 0):
QObject(parent), m_test(100) {
}
public:
QVariant getTest() {
return m_test;
}
void setTest(const QVariant &a_) {
m_test = a_;
emit TestChanged(a_);
qDebug() << "setTest";
}
signals:
void TestChanged(QVariant a_);
private:
QVariant m_test;
};
#endif // SETTINGS_H
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "settings.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Settings settings;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("settings", &settings);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
main.qml
import QtQuick 2.3
import QtQuick.Window 2.2
Window {
visible: true
x: settings.test
height: 320
width: 240
onXChanged: {
title = "x=" + x + ":test=" + settings.test;
}
MouseArea {
anchors.fill: parent
onClicked: {
settings.test += 50;
}
}
}
В сторону QML работает, при любом изменении св-ва test тут же меняется и связанное свойство в QML. А вот наоборот нифига. Причем у QML-го Settings это работает, вопрос собственно простой: Что я делаю не так ?
И в догонку, а вообще как кто решает проблему хранения и отображения настроек в интерфейсе ?