[Qt-qml] Settings / State Saving proposal for QML
Alan Alpert
alan.alpert at nokia.com
Mon Nov 21 23:58:04 CET 2011
On Mon, 21 Nov 2011 19:30:25 João Abecasis wrote:
> Alan Alpert wrote:
> > On Fri, 18 Nov 2011 17:55:10 Abecasis Joao (Nokia-MP-Qt/Oslo) wrote:
> >> Alan Alpert wrote:
> >>> The idea is good, but I don't like the use of aliases in the example.
> >>> If you wanted to arbitrarily save/load properties perhaps an attached
> >>> object would be more appropriate, something like:
> >>>
> >>> Rectangle{
> >>>
> >>> height: 100
> >>> width: 100
> >>> Settings.persist: ["height", "width"] //If saved data
> >>>
> >>> available, sets on creation. Saves data on destruction.
> >>> }
> >>>
> >>> It's not just the complexities of aliases, the data really is in the
> >>> Rectangle element and that's where it should be seen to persist - not
> >>> due to some magic in a Settings element buried randomly in the code.
> >>
> >> How would you handle data that is read from Settings, but not saved
> >> back? An example is the color element in my example above.
> >
> > There is no such data if it's pure QML? What usecase would there be to
> > save data but never read it back? I could understand defaults and
> > conditional loading of course, but these can also be done with attached
> > objects, something like one of the below options presumably:
> >
> > Settings.save: ["color"]
> > Settings.load: ["color"]
> > onPropertySaysSo: Settings.load("color");
>
> (I suppose it was just a typo, but I'll point it out, anyway: *read* data
> but never *save* it back.)
It wasn't a typo, it was me misreading your sentence ;) .
However, how would it work to read persistent data with defaults, like in your
color example?
Settings{
property variant color: "blue"
}
The interpretation of this QML is that blue will be stored in the property
upon instantiation. Will the settings object simply overwrite such defaults if
it can find a data entry? If so, how will you clear or reset this data store
if you want to go back to "blue"?
> Use cases could be setting defaults, as you mention.
>
> It would be any state that is configurable but that the application (or the
> current component) has no way of changing and the developer decided to
> make that explicit by not binding changes back to persistent storage.
This makes no sense until A) There is some settings sharing possible between
applications/components or B) C++ Access is added. And even then it's a little
dubious.
Without either of those, then the state is configurable but nothing can change
the configuration - no real need to save settings then ;) .
How would you accomplish A)? It sounds like that's what you were thinking of,
but property API compartmentalization suggest that components shouldn't start
accessing the properties or settings of the programs they're embedded in. You
certainly don't want them setting things.
With B), how is this distinguished from the current approach of storing
settings in C++ and exposing a QObject? Would this just be a convenience or is
it supposed to provide something more?
> > So you'd have the Settings attached object which can operate on
> > properties, saving and loading as required. The problem is identifying
> > this same object again the next time the program is run, now that I
> > think about it. But you'd have similar problems with multiple Settings{}
> > items - how were you going to solve that? I.e. what happens below after
> > a few runs of the application?
> >
> > Rectangle{
> >
> > color: setting.color
> > Settings{
> >
> > id: setting
> > property variant color: "blue"
> >
> > }
> >
> > Settings{
> >
> > property variant color: "red"
> >
> > }
> >
> > }
>
> Not with the quick hack I wrote, but ideally, both properties would map to
> the same key in "SettingsSpace". Which value is picked up as the default
> would remain unspecified, but after one value is saved the same value
> should be consistently read back.
>
> The developer could use the group property to distinguish the two color
> properties in SettingsSpace. You otherwise get what you ask for.
>
> >> The idea here is to provide a way to gather (and save) information from
> >> a (platform-specific) standard location and be able to use it seamlessly
> >> in QML applications. The possibility to use aliases is an admittedly
> >> very cool side effect.
> >>
> >>> If you just want to save data back and forth, the Settings like object
> >>> works well though. Presumably you'd want to have a way to explicitly
> >>> save/load the data if you don't want to use the platform backend?
> >>
> >> Well, the way I want it, there should be nothing but a platform-specific
> >> backend. I don't want this to become a generic file loading/saving
> >> mechanism.
> >
> > Even if it's not a generic file loading/saving mechanism you still want a
> > way to get the data out of there. JSON-ifying the object could be enough
> > though, if it's all properties on the item.
>
> Yes, I'm only considering properties.
>
> I guess there could be a way to read/write all application settings as a JS
> object. In that case, you'd lose dynamic updates and change notifications.
> I haven't given any thought to that, though.
>
> >> Also, for platforms where this is supported (not with QSettings,
> >> though), runtime changes to configuration data could be transparently
> >> fed back to the application.
> >>
> >>> If it ends up like QSettings (I can't just ignore that fact ;) ) then
> >>> you'd probably want to have groups handled through the object
> >>> hierarchy, e.g. Settings{
> >>>
> >>> file: "settings.ini" //You seem to be missing this property ;)
> >>> Settings{
> >>>
> >>> group: "Alpha"
> >>> Settings{
> >>>
> >>> group: "Beta"
> >>> property int foo: 34
> >>>
> >>> }
> >>>
> >>> }
> >>>
> >>> }
> >>>
> >>> Would save [Alpha/Beta] foo=34 (or whatever).
> >>
> >> What's the use case for being able to specify a filename? Is it just
> >> because QSettings can?
> >
> > ... er, yes. It seems I over-estimated the QSettings influence. With the
> > use- case now stated it seems perfectly reasonable to scrap files and
> > groups.
>
> (At the moment, I'm keeping groups. I find it useful and it's currently the
> only namespacing mechanism -- besides property names, that is.)
>
> >>> If you don't want to prototype it with QSettings, perhaps you should
> >>> use the offline storage API like SameGame. It would still be a nice
> >>> convenience item to automatically store and load properties from SQL.
> >>> Then you could also prototype it in pure QML.
> >>
> >> I'm looking into some sort of Settings API that can be used from both
> >> the QML and C++ side. Also, on a platform where settings end up in a
> >> central location or where there are external means to change the data, I
> >> want that to remain available and the QML Application to notice those
> >> changes.
> >
> > Ah, so that's the usecase! Thanks for sharing ;) .
>
> Sorry for not making that clear before ;-)
>
> > Do you have any more
> > concrete examples though? Should SameGame/Snake switch to this for
> > storing its highscores, or is this meant for simpler data (and they
> > should stick to offline storage)?
>
> I don't have more concrete examples, as I just began exploring the problem
> space. That said, I'd want this to scale beyond just "simpler data". If
> SameGame/Snake can't be cleanly mapped with a Settings API, I say that
> doesn't bode well for the API.
>
That depends. The tabular data of high scores has a different format and
requirements to persisting x/y/w/h on an object. I certainly wouldn't use
QSettings to store that data - but we've established this isn't a QSettings
clone ;) . What is an example of data too large or complex for you to want
this API to cover? Or does it do *EVERYTHING*?
--
Alan Alpert
Senior Engineer
Nokia, Qt Development Frameworks
More information about the Qt-qml
mailing list