declare global property in QML for other QML files

I want to declare a global property in a config file and use it in other files. for example declare mainbg in:

Style.qml:

property color mainbg: 'red'

and use it in other QML files (like view.qml and main.qml). How can I do this work?

Answers


Use a QML Singleton.

Please reference "Approach 2" on this page -- The ugly QTBUG-34418 comments are mine.

These are the pieces you need:

Style.qml

pragma Singleton
import QtQuick 2.0
QtObject {
    property color mainbg: 'red'
}

qmldir

This file must be in the same folder as the singleton .qml file (Style.qml in our example) or you must give a relative path to it. qmldir may also need to be included by the .qrc resource file. More information about qmldir files can be found here.

# qmldir
singleton Style Style.qml

How to Reference

import QtQuick 2.0
import "."  // this is needed when referencing singleton object from same folder
Rectangle {
    color: Style.mainbg  // <- there it is!!!
    width: 240; height 160
}

This approach is available since Qt5.0. You need a folder import statement even if referencing the QML singleton in the same folder. If is the same folder, use: import "." This is the bug that I documented on the qt-project page (see QTBUG-34418, singletons require explicit import to load qmldir file).


Basically, if you don't need property binding (if you value is a constant and will not need to be notifiable on change) you can define it in a Javascript shared library, like this :

// MyConstants.js
.pragma library
var mainbg = "red";

And use it in QML like this :

import "MyConstants.js" as Constants

Rectangle {
     color: Constants.mainbg;
}

But the bad side of this are : - no strong typing (JS doesn't really know about types) so you could put anything even if it is not a color. - and if you change mainbg, the Item using it won't be notified about the change and will keep the old value

So if you need type checking and binding/change notify, simply declare your property as a member of the root object in you main.qml, and it will be accessible from everywhere in the QML application, because the property will in fact be directly registered into the Qml Context object, which is global by definition.

Hope it helps.


You can create a js file and import it to all of the files that have to use this property.

js file:

//Note: you only need '.pragma library' if you are planning to
//change this variable from multiple qml files
.pragma library
var globalVariable = 20;

qml file:

import "test.js" as Global

Rectangle {
  id: main
  width: 300; height: 400

  Component.onCompleted: {
    console.log( Global.globalVariable)
    //you can also change it
    Global.globalVariable = 5
  }
}

Adding some contribute to @pixelgrease answer, I found another technique that doesn't require the path relative import ".", workarounding the bug QTBUG-34418. This is useful especially if one has qmldir and singleton class in a different place than the qml file where the singleton is used. The technique requires defining a proper module inside the tree structure: the module is then resolved by adding the parent path of the module to the QML engine with QmlEngine::addImportPath(moduleParentPath). For example:

qml/
├── <ModuleName>/
│ ├── <ClassName>.qml
│ ├── qmldir

In main.cpp you have then:

QQmlApplicationEngine engine;
engine.addImportPath("qrc:/qml");    // Can be any directory
engine.load("qrc:/qml/main.qml");

If you use resources, qml.qrc:

<RCC>
 <qresource prefix="/">
      (...)
 <file>qml/main.qml</file>
 <file>qml/MySingletons/MySingleton.qml</file>
 <file>qml/MySingletons/qmldir</file>
 </qresource>
</RCC>

In qmldir:

module MySingletons
singleton MySingleton 1.0 MySingleton.qml

In main.qml, or any other qml file in a different directory:

import MySingletons 1.0

Then you use MySingleton class as usual. I attached the example MySingletonWithModule.7z to bug QTBUG-34418 for reference.


Add this property in main and you can access it in any qml,this may not be the correct way but this works.

or if you want to group the property add them in a qml include that qml in main and give an id,now you can access this property using that id

main.qml

 Item{
 width:10
 height:10

 Model{
 id:globdldata
 }



 }

Model.qml

Item {

property color mainbg: 'red'

}

you can use globdldata.mainbg anywhere


You can always create a new QML object file that contains the properties that you want shared across qml files. Just import it the same way you would any QML object and you have access to properties. Now, if you want to be able to modify these properties and have the changes shared across instances things get a lot trickier and you will most likely want to resort to some sort of solution using the .pragma library js files. Unless you want to write some sort of C++ alternative.


Need Your Help

How to save an HTML5 Canvas as an image on a server?

javascript php ajax html5-canvas

I'm working on a generative art project where I would like to allow users to save the resulting images from an algorithm. The general idea is:

Load arrayList data into JTable

java swing arraylist jtable grid-layout

I'm trying to set items from a method called FootballClub and so far it's fine.