2012-07-05 16 views
8

Prendete questo codice:QML portata componente di puzzle

import QtQuick 1.1 

Rectangle { 
    width: 100 
    height: 100 

    property color fromColor: "red" 
    property color toColor: "blue" 

    gradient: Gradient { 
     property color fromColor: "yellow" 
     property color toColor: "green" 

     GradientStop { position: 0; color: fromColor } 
     GradientStop { position: 1; color: toColor } 
    } 
} 

Perché esattamente il Gradient raccogliere le sue fromColor e toColor proprietà dall'elemento di recinzione?

Dove è documentato (almeno all'interno dei commenti del codice sorgente, meglio all'interno dei documenti ufficiali)?

Nota: questo "esempio offuscamento QML è dal discorso di Girish Ramakrishnan Qt Quick Best Practices and Design Patterns (riavvolgimento al 25 '), dove si fa dire che la cosa è estremamente complicata e deve con ambito dei componenti e del genere, ma non ha tempo di spiegare perché.

[UPDATE]

Così, come Martinj racconta di seguito, il componente di livello superiore nell'elemento-proprietà (non solo elemento-bambino) gerarchia ha le sue proprietà visibili a tutte le proprietà tuttavia profondamente annidato, con la precedenza delle proprietà di quelle proprietà e di tutte le pr operazioni di elementi "intermedi" non visti affatto.

Ecco un piccolo esempio:

import QtQuick 1.1 

Item { 
    Item { 
     property string s: "parent-str" 
     Item { Component.onCompleted: console.log(s) } 
    } 
} 

Questo dà: "ReferenceError: Can't find variable: s"

E questo funziona come previsto:

import QtQuick 1.1 

Item { 
    property string s: "parent-str" 
    Item { Component.onCompleted: console.log(s) } 
} 

, l'output "parent-str".

Vedere i commenti di MartinJ qui sotto.

+0

"se siete interessati a sapere perché è il modo in cui è ... proprio non esitate a prendere me dopo il colloquio. " (Girish Ramakrishnan in quella conversazione). Bene, ratti. – cgmb

+0

@ Slavik81 Bene, il semplice riferimento all'argomento è stato molto utile, almeno. Inoltre, possiamo sempre mandargli una e-mail - se non ha dimenticato i dettagli rilevanti :) – mlvljr

+0

@ Slavik81 E 'stato chiarito, ha risposto Martin, e ho aggiornato la mia domanda con un esempio (spero) di chiarimento. – mlvljr

risposta

6

Questo certamente non sembra intuitivo a prima vista, ma commenta fromColor e toColor nell'elemento radice componente e la ragione diventa evidente. Dal QML Scope docs si può vedere che il campo di applicazione comprende:

  • tutti i 's id definite all'interno del componente.
  • proprietà locali
  • le proprietà dell'oggetto radice della Componente

A GradientStop {} nell'esempio precedente non ha proprietà locali definite. Il componente radice fa e sono le proprietà che risolvono fromColor e toColor. Le proprietà in Gradient {} non rientrano nel campo di applicazione dello GradientStop {}.

+0

Ok, ci penserò di nuovo, anche se mi piacerebbe fare alcune domande immediatamente (visto che ho già letto la pagina del documento di scoping un bel po 'di volte - per 4.7, ma sembra che nulla sia cambiato da allora). – mlvljr

+0

1. In primo luogo, se le proprietà del genitore vengono ignorate durante la ricerca del nome da parte dei bambini (come Gradient è un genitore di entrambi gli oggetti GradienStop), perché esempi come 'Item {property string s:" parent-str "; Articolo {Component.onCompleted: console.log (s)}} 'funziona a tutti (questo produce output" paren-str ")? – mlvljr

+0

2. Inoltre, l'altra metà del puzzzle nel discorso (collegato sopra) era che inserendo la definizione Gradiente (così com'è) in un file separato, si trovavano entrambe le proprietà interne del colore. – mlvljr

0

Vedi anche:

import QtQuick 1.1 

Item { 
    property string s: "outer" 

    Item { 
     property string s: "middle" 

     property Item it: Item { 
      property string dummy: function() { console.log("(5) s: "+s); "" }() 
      Component.onCompleted: console.log("(1) s: " + s) 
     } 

     Item { 
      property string dummy: function() { console.log("(4) s: "+s); "" }() 

      function f() { 
       console.log("(2) s: " + s) 
      } 

      Component.onCompleted: { 
       console.log("(3) s: " + s) 
       f() 
      } 
     } 
    } 
} 

questo uscite di codice:

(5) s: outer 
(4) s: outer 
(3) s: outer 
(2) s: outer 
(1) s: outer 

nota, che però (alla proprietà bambini o meno) e qualunque (un elemento o un frammento di codice JavaScript) che bind, la proprietà "middle" non viene mai trovata.

La ricerca del nome è dunque:

  1. di definito all'interno della voce o Component (vedi 3)
  2. proprietà locali
  3. proprietà di livello superiore di elemento (o dei componenti, nel caso in cui è definita in linea id, anche quando il nome "Componente" è omesso, come quando i delegati sono opportunamente definiti).

Inoltre, quando una proprietà viene fatto riferimento all'interno del componente, ma non definito in esso, ancora può essere introdotto all'interno del componente "misura", e si vedono:

//OverrideInner.qml 
import QtQuick 1.1 

Item { 
    Component.onCompleted: console.log(s) 
} 

.

//OverrideOuter.qml 
import QtQuick 1.1 

Item { 
    property string s: "overriden-outer" 

    Item { 
     property string s: "overriden-middle" 

     OverrideInner { 
      property string s: "overriden-inner" 
     } 
    } 
} 

Running "OverrideOuter.qml" produce:

overriden-inner 

Anche in questo caso, vedi i commenti di Martin e la documentazione per chiarire la questione. La documentazione in questione sono: