web-dev-qa-db-fra.com

déclarer une propriété globale dans QML pour d'autres fichiers QML

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?

24
2 8

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).

37
pixelgrease

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.

23
TheBootroo

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
  }
}
20
JuliusG

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.

5
ceztko

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ù

2
Bibin

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++.

1
Deadron