Je veux déclarer une propriété globale dans un fichier de configuration et l'utiliser dans d'autres fichiers. par exemple, déclarer mainbg
dans:
Style.qml:
property color mainbg: 'red'
et l'utiliser dans d'autres fichiers QML (comme view.qml
et main.qml
). Comment puis-je faire ce travail?
Utilisez un singleton QML.
Veuillez faire référence à "Approche 2" sur cette page - Les commentaires laids QTBUG-34418 sont les miens.
Ce sont les pièces dont vous avez besoin:
Style.qml
pragma Singleton
import QtQuick 2.0
QtObject {
property color mainbg: 'red'
}
qmldir
Ce fichier doit se trouver dans le même dossier que le fichier .qml singleton (Style.qml
dans notre exemple) ou vous devez lui donner un chemin relatif. qmldir
peut également avoir besoin d'être inclus dans le fichier de ressources .qrc. Plus d'informations sur les fichiers qmldir peuvent être trouvées ici .
# qmldir
singleton Style Style.qml
Comment faire référence
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
}
Cette approche est disponible depuis Qt5.0. Vous avez besoin d'une instruction de dossier import
même si vous faites référence au singleton QML dans le même dossier. S'il s'agit du même dossier, utilisez: import "."
C'est le bogue que j'ai documenté sur la page qt-project (voir QTBUG-34418, les singletons nécessitent une importation explicite pour charger le fichier qmldir).
Fondamentalement, si vous n'avez pas besoin de liaison de propriété (si votre valeur est une constante et n'a pas besoin d'être notifiée lors du changement), vous pouvez la définir dans une bibliothèque partagée Javascript, comme ceci:
// MyConstants.js
.pragma library
var mainbg = "red";
Et utilisez-le en QML comme ceci:
import "MyConstants.js" as Constants
Rectangle {
color: Constants.mainbg;
}
Mais le mauvais côté de ceci est: - pas de frappe forte (JS ne connaît pas vraiment les types) donc vous pouvez mettre n'importe quoi même si ce n'est pas une couleur. - et si vous modifiez mainbg
, l'élément qui l'utilise ne sera pas informé de la modification et conservera l'ancienne valeur
Donc, si vous avez besoin de vérification de type et de notification de liaison/modification, déclarez simplement votre propriété en tant que membre de l'objet racine dans votre fichier main.qml, et il sera accessible de partout dans l'application QML, car la propriété sera en fait directement enregistrée dans l'objet Contexte Qml, qui est global par définition.
J'espère que cela aide.
Vous pouvez créer un fichier js et l'importer dans tous les fichiers qui doivent utiliser cette propriété.
fichier js:
//Note: you only need '.pragma library' if you are planning to
//change this variable from multiple qml files
.pragma library
var globalVariable = 20;
fichier qml:
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
}
}
En ajoutant une contribution à la réponse @pixelgrease, j'ai trouvé une autre technique qui ne nécessite pas le chemin relatif import "."
, Contournant le bogue QTBUG-34418 . Ceci est particulièrement utile si l'on a qmldir
et la classe singleton à un endroit différent du fichier qml où le singleton est utilisé. La technique nécessite de définir un module approprié à l'intérieur de l'arborescence: le module est ensuite résolu en ajoutant le chemin parent du module au moteur QML avec QmlEngine::addImportPath(moduleParentPath)
. Par exemple:
qml/
├── <ModuleName>/
│ ├── <ClassName>.qml
│ ├── qmldir
Dans main.cpp vous avez alors:
QQmlApplicationEngine engine;
engine.addImportPath("qrc:/qml"); // Can be any directory
engine.load("qrc:/qml/main.qml");
Si vous utilisez des ressources, qml.qrc:
<RCC>
<qresource prefix="/">
(...)
<file>qml/main.qml</file>
<file>qml/MySingletons/MySingleton.qml</file>
<file>qml/MySingletons/qmldir</file>
</qresource>
</RCC>
Dans qmldir:
module MySingletons
singleton MySingleton 1.0 MySingleton.qml
Dans main.qml, ou tout autre fichier qml dans un répertoire différent:
import MySingletons 1.0
Ensuite, vous utilisez la classe MySingleton comme d'habitude. J'ai attaché l'exemple MySingletonWithModule.7z au bug QTBUG-34418 pour référence.
Ajoutez cette propriété dans main et vous pouvez y accéder dans n'importe quel qml, ce n'est peut-être pas la bonne façon mais cela fonctionne.
ou si vous voulez grouper la propriété, ajoutez-les dans un qml, incluez ce qml dans main et donnez un id, vous pouvez maintenant accéder à cette propriété en utilisant cet id
main.qml
Item{
width:10
height:10
Model{
id:globdldata
}
}
Model.qml
Item {
property color mainbg: 'red'
}
vous pouvez utiliser globdldata.mainbg n'importe où
Vous pouvez toujours créer un nouveau fichier objet QML qui contient les propriétés que vous souhaitez partager entre les fichiers qml. Importez-le simplement de la même manière que n'importe quel objet QML et vous avez accès aux propriétés. Maintenant, si vous voulez pouvoir modifier ces propriétés et partager les changements entre les instances, les choses deviennent beaucoup plus difficiles et vous voudrez probablement recourir à une sorte de solution en utilisant les fichiers js de la bibliothèque .pragma. Sauf si vous voulez écrire une sorte d'alternative C++.