qml settings
DESCRIPTION
Update: Minor updates for the local meego meetup. How do you make your QML based applications automatically scalable to different platforms, yet pixel-perfect finetunable when needed. We used this approach for the first real application that works and looks good on Symbian, MeeGo/Harmattan and Android: - http://store.ovi.com/content/186742 - https://market.android.com/details?id=eu.licentia.necessitas.industrius.example.dicountcalcandroid This is presentation from the 2nd Tampere Barcamp http://barcamp.org/w/page/39167337/BarCampTampere2 and may mean not too much for you if you haven't been present live. More material like this can be found at http://agilesoftwaredevelopment.com/tags/qmlTRANSCRIPT
Platform and device-specific settings for your QML layouts
Artem MarchenkoOctober 8, 2011
After Easy Discount Calculator by Artem Marchenko, Jarmo Parkkinen, Tuukka Lindroos and Ekaterina Kuts
Technical solution by Artem Marchenko and Tuukka Lindroos
Artem Marchenko
Was a Product Manager shipping multi-hundred MEur products
Three times Forum Nokia Champion
Private entrepreneurAvailable for hire for all things QML
Product Manager, Agile Coach, QML engineer for hire
http://fi.linkedin.com/in/artemmarchenko
Same app running on Harmattan, Android and Symbian
Easy Discount Calculator
• Symbian, MeeGo/Harmattan - http://store.ovi.com/content/186742
• Android - http://bit.ly/discountcalculator– Free, but has font issues on some models
due to porting technology bug.– Well working proof of concept for now
All the parameters can be fine-tuned on desktop
Settings system// SettingsBase.QMLimport Qt 4.7import "GlobalSettings.js" as Js QtObject { id: settingsObject // logical switches/conditions property bool exitButtonPresent: true property bool clearButtonIsBetweenTheLines: true // element sizes property int rollerHeight: 110 property int digitRollerWidth: 56 property int percentageRollerWidth: digitRollerWidth
Settings system
// SettingsMaemo.qmlimport Qt 4.7
SettingsBase { property string platformTitle: "Maemo" property int screenWidthInPortrait: 480... property int rollerHeight: 160 property int rollerNumberLineInnerSpacing: 0 property int digitRollerWidth:69 statusLineHeight: 0
Tree of settings
SettingsBase
SettingsSymbian SettingsHarmattan
SettingsAndroid480x800
Using platform settings in JS//GlobalSettings.js.pragma library // - the only QML possibility for global variablesvar globalSettings = null
// Will fetch the settings object from the item. If the settings object doesn't // exists, will return the global one or generate one on the fly based on base settings. function getSettings(item) {… if(item.settings) { if(!globalSettings) { globalSettings = item.settings }
if(!globalSettings) { var component = Qt.createComponent("SettingsBase.qml") globalSettings = component.createObject(item) } return globalSettings;
Using Settings in QML
// SmallButton.qml
import Qt 4.7import "GlobalSettings.js" as Js
Rectangle { id: button
width: Js.getSettings(button).smallButtonWidth height: Js.getSettings(button).smallButtonHeight radius: 3
Injecting Settings from C++QString settingsPath = "qml/discountcalcui/Settings" + platformTitle + ".qml";
// localAdjustPath cares about platform-specific file location detailssettingsUrl = QUrl::fromLocalFile(CrossPlatformUtils::localAdjustPath(settingsPath));QDeclarativeComponent component(view.engine(), settingsUrl); settingsInstance = component.create();
if(!settingsInstance) { // No settings found - no object to install qWarning() << "Settings not found for this platform!"; qWarning() << component.errorString();} else {settingsInstance->setProperty("shouldInitializeGlobalSettingWithItself", true); view.engine()->rootContext()->setContextProperty("forcedSettings”, settingsInstance); }
// continue with normal QML initialization
JavaScript side of initialization//SettingsBase.qml
import Qt 4.7import "GlobalSettings.js" as Js
QtObject { id: settingsObject
property bool shouldInitializeGlobalSettingWithItself: false
// Is executed way before main QML file is loaded onShouldInitializeGlobalSettingWithItselfChanged: { if(shouldInitializeGlobalSettingWithItself) { console.log("SBase: initializing global settings with " + settingsObject) Js.globalSettings = settingsObject } }
Switching settings for desktop simulation
// Simulator for different platforms
DiscountCalcUi { id: main }
ListModel { id: platformsModel ListElement {title: "Symbian"; visualTitle: "S^3"} ListElement {title: "Android480x800"; visualTitle: "Andr 800" } ListElement {title: "Harmattan" } }
onButtonClicked: { var component = Qt.createComponent("Settings" + model.title + ".qml") main.settings = component.createObject(main) }// actually, maybe we should have changed the global JS reference :/
Summary
• Parameterizing code everywhere is possible and easy
• Use JavaScript libraries for storing global objects
• To initialize settings by the moment of QML instantiations, inject settings from C++ before the main QML object
• Care about ability to change settings object for the desktop simulation of different platforms
Thank you
Q&As time
You can find these and similar slides at http://agilesoftwaredevelopment.com/tags/qml