declare global property in QML for other QML files
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.
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.
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
}
}