2013-03-06 17 views
19

Desidero dichiarare una proprietà globale in un file di configurazione e utilizzarla in altri file. per esempio dichiarare mainbg in:dichiarare la proprietà globale in QML per altri file QML

Style.qml:

property color mainbg: 'red' 

e utilizzarlo in altri file QML (come view.qml e main.qml). Come posso fare questo lavoro?

risposta

28

Utilizzare un QQ Singleton.

Fare riferimento a "Metodo 2" su this page - I brutti commenti di QTBUG-34418 sono miei.

Questi sono i pezzi necessari:

Style.QML

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

qmldir

Questo file deve essere nella stessa cartella del file di Singleton .qml (Style.qml nel nostro esempio) o si deve dare un percorso relativo ad esso. qmldir potrebbe anche essere necessario includere il file di risorse .qrc. Ulteriori informazioni sui file qmldir possono essere trovate here.

# qmldir 
singleton Style Style.qml 

Come al quale riferirsi

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 
} 

Questo approccio è disponibile dal Qt5.0. È necessaria una dichiarazione della cartella import anche se si fa riferimento al singleton QML nella stessa cartella. Se è la stessa cartella, utilizzare: import "." Questo è il bug che ho documentato sulla pagina del qt-project (vedi QTBUG-34418, i singleton richiedono un'importazione esplicita per caricare il file qmldir).

+0

Perché non solo un semplice file javascript '.pragma library'? – Matteo

17

È possibile creare un file js e importarlo in tutti i file che devono utilizzare questa proprietà.

js di file:

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

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

non dimenticarti di mettere la libreria #pragma qui. – user1095108

+5

Devo notare che il file '.pragma library' _allowes_ JS deve essere utilizzato da diversi file QML, ma _non garantisce che ci sarà una sola istanza della libreria. Ho appena riscontrato un grave errore nella mia applicazione dovuto al mio tentativo di utilizzare la libreria JS come contenitore di stato globale. – tonytony

1

È sempre possibile creare un nuovo file oggetto QML che contiene le proprietà che volete condividere attraverso i file QML. Basta importarlo nello stesso modo in cui si farebbe con qualsiasi oggetto QML e si ha accesso alle proprietà. Ora, se vuoi essere in grado di modificare queste proprietà e avere le modifiche condivise tra le varie istanze, le cose diventano molto più complicate e molto probabilmente vorrai ricorrere a qualche tipo di soluzione usando i file js della libreria .pragma. A meno che tu non voglia scrivere una sorta di alternativa al C++.

20

In sostanza, se non avete bisogno di proprietà di associazione (se il valore è una costante e non sarà necessario essere a notifica sul cambiamento) è possibile definire in una libreria condivisa JavaScript, in questo modo:

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

e utilizzarlo in QML come questo:

import "MyConstants.js" as Constants 

Rectangle { 
    color: Constants.mainbg; 
} 

Ma il lato cattivo di questo sono: - senza tipizzazione forte (JS non sa realmente sui tipi) così si potrebbe mettere qualsiasi cosa, anche se non è un colore. - e se si modifica mainbg, l'articolo che lo utilizza non verrà informato della modifica e manterrà il vecchio valore

Quindi, se è necessario digitare controllo e associazione/modifica notifica, è sufficiente dichiarare la proprietà come membro di l'oggetto root in main.qml, e sarà accessibile da qualsiasi punto dell'applicazione QML, poiché la proprietà verrà infatti registrata direttamente nell'oggetto Context Qml, che è globale per definizione.

Spero che aiuti.

1

Aggiungi questa proprietà in main e puoi accedervi in ​​qualsiasi qml, questo potrebbe non essere il modo corretto ma funziona.

o se si desidera raggruppare la proprietà aggiungerli in un QML comprendono che QML in principale e dare un id, ora è possibile accedere a questa struttura tramite che id

main.qml

Item{ 
width:10 
height:10 

Model{ 
id:globdldata 
} 



} 

Model.qml

Item { 

property color mainbg: 'red' 

} 

si può usare ovunque globdldata.mainbg

3

Aggiungendo un po 'di contributo alla risposta @pixelgrease, ho trovato un'altra tecnica che non richiede il percorso relativo import ".", che risolve il bug QTBUG-34418. Ciò è utile specialmente se uno ha qmldir e una classe singleton in un posto diverso dal file qml in cui viene utilizzato il singleton. La tecnica richiede la definizione di un modulo appropriato all'interno della struttura ad albero: il modulo viene quindi risolto aggiungendo il percorso genitore del modulo al motore QML con QmlEngine::addImportPath(moduleParentPath). Per esempio:

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

In main.cpp si dispone poi:

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

Se si utilizzano le risorse, 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 o qualsiasi altro file qml in una directory diversa ectory:

import MySingletons 1.0 

Quindi si usa la classe MySingleton come al solito. Ho allegato l'esempio MySingletonWithModule.7z al bug QTBUG-34418 come riferimento.