2013-03-06 9 views
19

Ich möchte eine globale Eigenschaft in einer Konfigurationsdatei deklarieren und in anderen Dateien verwenden. zum Beispiel erklärt mainbg in:deklarieren globale Eigenschaft in QML für andere QML-Dateien

Style.qml:

property color mainbg: 'red' 

und es in anderen QML-Dateien (wie view.qml und main.qml) verwenden. Wie kann ich diese Arbeit machen?

Antwort

28

Verwenden Sie einen QML Singleton.

Bitte verweisen "Approach 2" auf this page - Die hässlichen QTBUG-34418 Kommentare gehören mir.

Dies sind die Stücke, die Sie brauchen:

Stil.qml

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

qmldir

Diese Datei im selben Ordner sein muss als die Singleton (Style.qml in unserem Beispiel) Datei .qml oder Sie müssen einen relativen Pfad geben. Möglicherweise muss auch qmldir in die .qrc-Ressourcendatei aufgenommen werden. Weitere Informationen zu qmldir-Dateien finden Sie unter here.

# qmldir 
singleton Style Style.qml 

Wie

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 
} 

Dieser Ansatz zur Referenz ist seit Qt5.0 verfügbar. Sie benötigen einen Ordner import Anweisung, selbst wenn Sie den QML Singleton im selben Ordner referenzieren. Wenn derselbe Ordner ist, verwende: import "." Dies ist der Fehler, den ich auf der qt-Projektseite dokumentiert habe (siehe QTBUG-34418, Singletons erfordern einen expliziten Import, um die qmldir-Datei zu laden).

+0

Warum nicht einfach eine einfache .pragma-Bibliotheks-JavaScript-Datei? – Matteo

17

Sie können eine js-Datei erstellen und sie in alle Dateien importieren, die diese Eigenschaft verwenden müssen.

js-Datei:

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

qml Datei:

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 
    } 
} 
+1

vergessen Sie nicht, '#pragma library' dort zu setzen. – user1095108

+5

Ich muss beachten, dass '.pragma library' _allows_ JS-Datei von mehreren QML-Dateien verwendet werden soll, aber _ garantiert nicht, dass es nur eine Instanz der Bibliothek geben wird. Ich habe gerade einen schwerwiegenden Fehler in meiner Anwendung festgestellt, der auf meinem Versuch beruht, die JS-Bibliothek als globalen Statuscontainer zu verwenden. – tonytony

1

Sie können jederzeit eine neue QML Objektdatei erstellen, die die Eigenschaften enthält, die Sie über qml Dateien gemeinsam genutzt werden sollen. Importieren Sie es einfach wie jedes QML-Objekt und Sie haben Zugriff auf Eigenschaften. Nun, wenn Sie in der Lage sein möchten, diese Eigenschaften zu ändern und die Änderungen zwischen den Instanzen geteilt zu bekommen, werden die Dinge viel komplizierter und Sie werden höchstwahrscheinlich zu einer Lösung mit den .pragma-Bibliothek-js-Dateien greifen wollen. Es sei denn, Sie möchten eine Art C++ - Alternative schreiben.

20

Grundsätzlich, wenn Sie nicht Eigentum brauchen Bindung (wenn Sie Wert auf eine Konstante ist und wird nicht meldepflichtig auf Änderung sein müssen) Sie es in einer Javascript gemeinsam genutzte Bibliothek definieren, wie folgt aus:

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

Und es in QML wie folgt verwenden:

import "MyConstants.js" as Constants 

Rectangle { 
    color: Constants.mainbg; 
} 

Aber die schlechte Seite hierfür sind: - keine starke Typisierung (JS wirklich nicht über Typen wissen), so könnte man alles selbst setzen, wenn es sich nicht um eine Farbe. - und wenn Sie mainbg ändern, das Element, um es mit nicht über die Änderung informiert werden und den alten Wert

So behalten, wenn Sie die Typprüfung und die Bindung/ändern müssen notify, indem Sie die Eigenschaft als Mitglied erklären Das Root-Objekt in Ihrer Datei main.qml, auf das von überall in der QML-Anwendung aus zugegriffen werden kann, da die Eigenschaft tatsächlich direkt im Qml-Kontextobjekt registriert wird, das per Definition global ist.

Ich hoffe, es hilft.

1

Fügen Sie diese Eigenschaft in main hinzu und Sie können in jedem qml darauf zugreifen, dies ist möglicherweise nicht der richtige Weg, aber das funktioniert.

oder wenn Sie die Eigenschaft fügen Sie sie in einer qml gruppieren möchten umfassen, dass qml in Haupt- und eine ID geben, jetzt können Sie diese Eigenschaft zugreifen verwenden, die id

main.qml

Item{ 
width:10 
height:10 

Model{ 
id:globdldata 
} 



} 

Model.qml

Item { 

property color mainbg: 'red' 

} 

können Sie überall verwenden globdldata.mainbg

3

Hinzufügen von etwas zu @pixelgrease Antwort beitragen, fand ich eine andere Technik, die nicht den Pfad relativ import ".", Workarounding der Fehler QTBUG-34418. Dies ist besonders nützlich, wenn eine qmldir- und Singleton-Klasse an einer anderen Stelle als die qml-Datei verwendet wird, in der der Singleton verwendet wird. Die Technik erfordert das Definieren eines geeigneten Moduls innerhalb der Baumstruktur: Das Modul wird dann aufgelöst, indem der übergeordnete Pfad des Moduls zur QML-Engine mit QmlEngine::addImportPath(moduleParentPath) hinzugefügt wird. Zum Beispiel:

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

In main.cpp haben Sie dann:

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

Wenn Sie Ressourcen verwenden, 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 oder einer anderen qml-Datei in einem anderen Verzeichnis Quelle:

import MySingletons 1.0 

Dann verwenden Sie MySingleton-Klasse wie gewohnt. Ich habe das Beispiel MySingletonWithModule.7z als Referenz an den Fehler QTBUG-34418 angehängt.