[SOLVED] Using QSettings from QML
-
wrote on 3 Dec 2013, 21:15 last edited by
Hello
I'm new to the forum and pretty new to QT5 development with QML as well.
I've got an application using some C++ objects and QML for the GUI.
I'm tryng to store values in a .conf file using QSettings.
I am creating a settings object my main object:
@
application.h:
#include <QSettings>class RS232VisualizerMain : public QObject
{
Q_OBJECT
private:SerialConnect* serialPort; QSettings* appSettings;
}
application.cpp:
RS232VisualizerMain::RS232VisualizerMain(QObject *parent) :
QObject(parent)
{
appSettings = new QSettings;
appSettings->setValue("main/test","test");
}
@I can save values from my C-class using the code above.
However, I couldn't figure out how to write settings from the QML code. I'm trying to set the object as a context property and writing to it from qml:
@
application.cpp:
engine = new QQmlEngine;//export context properties to qml
engine->rootContext()->setContextProperty("appSettings",appSettings);
component = new QQmlComponent(engine); component->loadUrl(QUrl("qrc:/qml/main.qml")); if ( !component->isReady() ) { qWarning("%s", qPrintable(component->errorString())); return 1; } topLevel = component->create(); window = qobject_cast<QQuickWindow *>(topLevel); if ( !window ) { qWarning("Error: Your root item has to be a Window."); return 1; } window->show();
main.qml:
Component.onCompleted: {
appSettings.setValue("serialPort/BAUD", "9600")
}
@With the setValue statement in QML like this, the application crashes on startup with exit code 0
I'm certainly missing something obvious. Any hint to tutorials, documentation or existing forum threads is appreciated.
-
the QSettings class doesn't have any callable methods out of QML.
For this they would have defined as SLOTS or with the Q_INVOKABLE macro.
You can write a wrapper class for your QSettings object which has such callable methods and forwards them to the QSettings instance. Then set this wrapper class as context-property. -
wrote on 4 Dec 2013, 18:35 last edited by
Thank you for the explanation. It helps me very much to understand what's going on. I've now created a wrapper class, according to the example given in this thread:
http://qt-project.org/forums/viewthread/11696/#64044I can create an object of the wrapper class and also add values from C++. However, my applications still crashes on startup if I'm trying to set a value from QML. This is how my code looks now:
@
appSettings.h:
#ifndef APPSETTINGS_H
#define APPSETTINGS_H
#include <QSettings>
#include <QCoreApplication>class appSettings : public QSettings
{
Q_OBJECTpublic:
explicit appSettings(QObject *parent = 0) : QSettings(QSettings::UserScope,
QCoreApplication::instance()->organizationName(), QCoreApplication::instance()->applicationName(), parent) {}Q_INVOKABLE inline void setValue(const QString &key, const QVariant &value) { QSettings::setValue(key, value); } Q_INVOKABLE inline QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const { return QSettings::value(key, defaultValue); }
};
Q_DECLARE_METATYPE(appSettings*)#endif // APPSETTINGS_H
application.cpp:
staticSettings = new appSettings;
staticSettings->setValue("serialPort/test", "value");
@The above setValue statement works as intended.
@
application.cpp:
engine = new QQmlEngine;//export context properties to qml
engine->rootContext()->setContextProperty("staticSettings",staticSettings);
component = new QQmlComponent(engine); component->loadUrl(QUrl("qrc:/qml/main.qml")); if ( !component->isReady() ) { qWarning("%s", qPrintable(component->errorString())); return 1; } topLevel = component->create(); window = qobject_cast<QQuickWindow *>(topLevel); if ( !window ) { qWarning("Error: Your root item has to be a Window."); return 1; } window->show();
main.qml:
Component.onCompleted: {
staticSettings.setValue("serialPort/BAUD", "9600")
}
@EDIT:
And it is working like a charm! Thank you very much
P.S: You should of course create the staticSettings object first and then declare it as context property ;-) I did the two steps in different methods in reverse order and my applicaton crashed.
1/3