← Back to team overview

ubuntu-phone team mailing list archive

Global variables in QML

 

I am not much of a writer so I will just write about my experiences on this topic which can get very annoying if not understood well.

My first attempt :

   var globalNumber = 18; // in "script.js"

Yes the var part in there says local, but because it is not in a function, how it's local then? Well it is. Each QML Document that imports "script.js" has its own part of RAM where globalNumber is local. So setting globalNumber to 15 in "Item1.qml" resulted in no change in "Item2.qml", both importing "script.js".
So that failed.

My second attempt :

Defining all my globals in the root qml object. This made a lot of sense and worked fine for some time, before it broke today.
I am not sure why that happened :)

   MainView {
        property int globalNumber : 12; // no, doesn't work too,
   undefined reference to globalNumber errors
   }

My third (and hopefully final attempt) :

I created a dictionary in Qt that stays persistent accross the application lifecycle. I've also added a bit of sugar over it.
Here is the code for that :

   function isNull (name) {
        var object = Qt.globalVariables [name];

        return object === null;
   }

   function __get (name) {
        var globalVariables = Qt.globalVariables;

        if (globalVariables [name] === undefined)
            console.log ("GET : %0 is not defined. Use this variable at
   your own risk.".arg (name));

        if (isNull (name))
            console.log ("GET : %0 is not yet set.".arg (name));

        return globalVariables [name];
   }

   function __set (name, value) {
        Qt.globalVariables [name] = value;
   }

   // PUBLIC
   function initialize (objects) {
        if (Qt.globalVariables === undefined)
            Qt.globalVariables = objects;
        else
            console.log ("You have already called initialize. Nothing
   was changed");
   }

   function get (name) {
        return __get (name);
   }

   function set (name, value) {
        __set (name, value);
   }

   function modify (name, func) {
       set (name, func (get (name)));
   }

I am using it like this :

   // "MainDocument.qml"
   import "global_variables.js" as Globals

   Component.onCompleted: {
        var globals = {
            number: null,
        }

        Globals.initialize (globals);

        Globals.set ("number", 18);
   }

   // "SomeOtherDocument.qml"
   console.log (Globals.get ("number")); // 18
   Globals.set ("number", 52);

   // "ThirdDocument.qml"
   console.log (Globals.get ("number")); // 52

Any singleton object will do, but I have used Qt here.

And as a final note: Try to avoid global variables as much as possible.
They are a horrible and messy way to organize your source code.

I hope this will help you to be less annoyed by memory errors. :)

Follow ups