So, after some looking around and experimenting, this is what I got.
The singleton is used to collect all settings. This is where a c++ backend will be used to actually store the settings an disk, probably using QSettings. Through this it will (probably) be possible to config the settings (format, path, file name, stuff like that).
MySingleton.qml
pragma Singleton
import QtQuick 2.0
Item {
// holding all settings as key-value pairs
property var dataMap : ({})
// list to filter out all the inherited base properties
property var filterObject : { "x":"", "y":"", "z":"", "width":"", "height":"",....... }
}
This element is the base for the settings elements. It's purpose is to sync to the singleton, writing the settings to the dataMap and, if they already exist, read on startup (the reading is missing atm). For this it will perform reading and writing on construction and destruction and (later) provide signals and slots for this.
MySettings .qml
import QtQuick 2.11
import QtQml 2.11
Item{
id:base
Component.onCompleted: {
console.log("Settings Created")
for(var prop in this){
if(!MySingleton.filterObject.hasOwnProperty(prop) && typeof this[prop] !=="function" )
{
MySingleton.dataMap[prop] = this[prop];
var component = Qt.createComponent("BidirecionalBinding.qml");
if (component.status === Component.Ready) {
var binding = component.createObject(this,
{"first": this, "second": MySingleton.dataMap,
"firstProperty": prop, "secondProperty": prop} );
console.log()
}
}
}
}
Component.onDestruction: {
console.log("Destructing Settings")
for(var prop in this){
if(!MySingleton.filterObject.hasOwnProperty(prop) && typeof this[prop] !=="function" )
console.log(prop + "(" + typeof this[prop] +"): " + this[prop])
}
console.log(JSON.stringify(MySingleton.dataMap))
}
}
The BidirectionBinding uses two Binding elements to make one bidirectional binding. I tested it using two buttons and bound the labels, worked without problem. It's intention is to keep the map and the settings elements properties in sync.
BidirectionBinding.qml
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQml 2.11
Item {
id:bidirectionalBinding
property alias first: firstBinding.target
property alias second: secondBinding.target
property alias firstProperty: firstBinding.property
property alias secondProperty: secondBinding.property
property bool delayed: true
property alias firstWhen: firstBinding.when
property alias secondWhen: secondBinding.when
property alias firstValue: firstBinding.value
property alias secondValue: secondBinding.value
Binding { id: firstBinding; when: true; delayed: bidirectionalBinding.delayed; value: second[secondProperty] }
Binding { id: secondBinding; when: true; delayed: bidirectionalBinding.delayed; value: first[firstProperty] }
}
The last file it the main file. This is for testing and demonstation. Its just four buttons for printing and changing the values.
main.qml
import QtQuick 2.11
import QtQuick.Window 2.11
Window {
id: window
title: "Hello Settings"
visible: true
width: 280
height: 250
property MySettings settings: MySettings{
id: settings
property alias windowTitle: window.title
property alias rectWidth: rect.width
}
Rectangle {
id: rect
width: 80;height: 50;x: 50;y: 50;color: 'green'
Text { text: "Set Title"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter }
MouseArea {
anchors.fill: parent
onClicked: window.title = "Hello New Title"
}
}
Rectangle {
width: 80;height: 50;x: 150;y: 50;color: 'green'
Text { text: "Set Alias"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter }
MouseArea {
anchors.fill: parent
onClicked: settings.windowTitle = "Hello New Alias"
}
}
Rectangle {
width: 80;height: 50;x: 50;y: 150;color: 'green'
Text { text: "Set Map"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter }
MouseArea {
anchors.fill: parent
onClicked: MySingleton.dataMap["windowTitle"] = "Hello New Setting"
}
}
Rectangle {
width: 80;height: 50;x: 150;y: 150;color: 'green'
Text { text: "Print"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter }
MouseArea {
anchors.fill: parent
onClicked: {
console.log(settings.windowTitle)
console.log(JSON.stringify(MySingleton.dataMap))
console.log()
}
}
}
}
Thats it so far. The advantage of this approach is, that it can be used like the Settings element from Qt. Also, it can easily be added to existing code later, the original code won't have to be changed (most likely).
The problem right know, aside from missing things like the backend, are the bidirectional bindings. I get the error
qrc:/BidirecionalBinding.qml:21: TypeError: Cannot read property 'rectWidth' of null
qrc:/BidirecionalBinding.qml:21: TypeError: Cannot read property 'windowTitle' of null
(line 21 is where the first Binding is declared)
What do you think about this so far?