Gültigkeitsbereich und Namensauflösung
QML-Eigenschaftsbindungen, Inline-Funktionen und importierte JavaScript-Dateien werden alle in einem JavaScript-Gültigkeitsbereich ausgeführt. Der Gültigkeitsbereich bestimmt, auf welche Variablen ein Ausdruck zugreifen kann und welche Variable Vorrang hat, wenn zwei oder mehr Namen miteinander in Konflikt stehen.
Da der in JavaScript integrierte Geltungsbereichsmechanismus sehr einfach ist, erweitert QML ihn, damit er sich natürlicher in die QML-Spracherweiterungen einfügt.
JavaScript-Gültigkeitsbereich
Die Geltungsbereichserweiterungen von QML greifen nicht in den natürlichen Geltungsbereich von JavaScript ein. JavaScript-Programmierer können ihr vorhandenes Wissen wiederverwenden, wenn sie Funktionen, Eigenschaftsbindungen oder importierte JavaScript-Dateien in QML programmieren.
Im folgenden Beispiel addiert die Methode „ addConstant() “ 13 zu dem übergebenen Parameter, genau wie es der Programmierer erwarten würde, unabhängig vom Wert der Eigenschaften „ a “ und „ b “ des QML-Objekts.
QtObject {
property int a: 3
property int b: 9
function addConstant(b) {
var a = 13;
return b + a;
}
}Dass QML die üblichen Gültigkeitsbereichsregeln von JavaScript beachtet, gilt sogar für Bindungen. Diese absolut grauenhafte, abscheuliche Bindung weist der Eigenschaft ` a ` des QML-Objekts den Wert 12 zu.
Jeder JavaScript-Ausdruck, jede Funktion und jede Datei in QML verfügt über ein eigenes, eindeutiges Variablenobjekt. In einem Objekt deklarierte lokale Variablen stehen niemals in Konflikt mit lokalen Variablen, die in einem anderen Objekt deklariert wurden.
Typnamen und importierte JavaScript-Dateien
QML-Dokumente enthalten Importanweisungen, die die für das Dokument sichtbaren Typnamen und JavaScript-Dateien definieren. Zusätzlich zu ihrer Verwendung in der QML-Deklaration selbst werden Typnamen vom JavaScript-Code beim Zugriff auf angehängte Eigenschaften und Aufzählungswerte verwendet.
Die Wirkung eines Imports gilt für jede Eigenschaftsbindung und jede JavaScript-Funktion im QML-Dokument, auch für solche in verschachtelten Inline-Komponenten. Das folgende Beispiel zeigt eine einfache QML-Datei, die auf einige Aufzählungswerte zugreift und eine importierte JavaScript-Funktion aufruft.
import QtQuick 2.0
import "code.js" as Code
ListView {
snapMode: ListView.SnapToItem
delegate: Component {
Text {
elide: Text.ElideMiddle
text: "A really, really long string that will require eliding."
color: Code.defaultColor()
}
}
}Objekt im Bindungsbereich
Ein Objekt, das über eine Eigenschaftsbindung verfügt, wird als Geltungsbereichsobjekt der Bindung bezeichnet. Im folgenden Beispiel ist das Objekt „ Item “ das Geltungsbereichsobjekt der Bindung.
Item {
anchors.left: parent.left
}Bindungen haben ohne Qualifizierung Zugriff auf die Eigenschaften des Geltungsbereichsobjekts. Im vorherigen Beispiel greift die Bindung direkt auf die Eigenschaft ` parent ` von ` Item` zu, ohne dass ein Objektpräfix erforderlich ist. QML führt einen strukturierteren, objektorientierten Ansatz für JavaScript ein und erfordert daher nicht die Verwendung der JavaScript-Eigenschaft ` this `.
Beim Zugriff auf angehängte Eigenschaften aus Bindungen heraus ist aufgrund ihrer Interaktion mit dem Scope-Objekt Vorsicht geboten. Konzeptionell existieren angehängte Eigenschaften auf allen Objekten, auch wenn sie nur auf eine Teilmenge davon Auswirkungen haben. Folglich werden unqualifizierte Lesezugriffe auf angehängte Eigenschaften immer auf eine angehängte Eigenschaft des Scope-Objekts aufgelöst, was nicht immer der Absicht des Programmierers entspricht.
Beispielsweise fügt der Typ „ PathView “ seinen Delegaten interpolierte Werteigenschaften hinzu, abhängig von deren Position im Pfad. Da „ PathView “ diese Eigenschaften nur sinnvoll an das Wurzelobjekt im Delegaten anfügt, muss jedes Unterobjekt, das darauf zugreift, das Wurzelobjekt explizit qualifizieren, wie unten gezeigt.
Würde das „ Image “-Objekt das Präfix „ root “ weglassen, würde es versehentlich auf die nicht festgelegte, angehängte Eigenschaft „ PathView.scale “ an sich selbst zugreifen.
Komponentenbereich
Jede QML-Komponente in einem QML-Dokument definiert einen logischen Geltungsbereich. Jedes Dokument verfügt über mindestens eine Stammkomponente, kann aber auch andere Inline-Unterkomponenten enthalten. Der Geltungsbereich der Komponente ist die Vereinigung der Objekt-IDs innerhalb der Komponente und der Eigenschaften des Stammobjekts der Komponente.
Item {
property string title
Text {
id: titletype
text: "<b>" + title + "</b>"
font.pixelSize: 22
anchors.top: parent.top
}
Text {
text: titletype.text
font.pixelSize: 18
anchors.bottom: parent.bottom
}
}Das obige Beispiel zeigt eine einfache QML-Komponente, die oben eine Rich-Text-Titelzeichenfolge und unten eine kleinere Kopie desselben Textes anzeigt. Der erste Typ „ Text “ greift bei der Erstellung des anzuzeigenden Textes direkt auf die Eigenschaft „ title “ der Komponente zu. Da die Eigenschaften des Stammtyps direkt zugänglich sind, ist es ein Kinderspiel, Daten innerhalb der Komponente zu verteilen.
Der zweite Typ „ Text “ greift über eine ID direkt auf den Text des ersten Typs zu. IDs werden vom QML-Programmierer explizit angegeben und haben daher stets Vorrang vor anderen Eigenschaftsnamen (mit Ausnahme derjenigen im JavaScript-Gültigkeitsbereich). Selbst in dem unwahrscheinlichen Fall, dass das Scope-Objekt der Bindung im vorangegangenen Beispiel eine Eigenschaft „ titletype “ hätte, hätte die ID „ titletype “ dennoch Vorrang.
Komponenteninstanz-Hierarchie
In QML verbinden Komponenteninstanzen ihre Komponentengültigkeitsbereiche miteinander und bilden so eine Gültigkeitsbereichshierarchie. Komponenteninstanzen können direkt auf die Komponentengültigkeitsbereiche ihrer Vorfahren zugreifen.
Am einfachsten lässt sich dies anhand von Inline-Unterkomponenten veranschaulichen, deren Komponentenbereiche implizit als Kinder der übergeordneten Komponente definiert sind.
Item {
property color defaultColor: "blue"
ListView {
delegate: Component {
Rectangle {
color: defaultColor
}
}
}
}Die Komponenteninstanzhierarchie ermöglicht es Instanzen der Delegate-Komponente, auf die Eigenschaft „ defaultColor “ vom Typ „ Item “ zuzugreifen. Hätte die Delegate-Komponente eine Eigenschaft namens „ defaultColor “ gehabt, hätte diese natürlich Vorrang gehabt.
Die Hierarchie der Komponenteninstanz-Gültigkeitsbereiche erstreckt sich auch auf nicht in einer Zeile stehende Komponenten. Im folgenden Beispiel erstellt die Komponente „ TitlePage.qml “ zwei Instanzen von „ TitleText “. Auch wenn sich der Typ „ TitleText “ in einer separaten Datei befindet, hat er dennoch Zugriff auf die Eigenschaft „ title “, wenn er innerhalb von „ TitlePage “ verwendet wird. QML ist eine Sprache mit dynamischem Geltungsbereich – je nachdem, wo sie verwendet wird, kann die Eigenschaft „ title “ unterschiedlich aufgelöst werden.
// TitlePage.qml
import QtQuick 2.0
Item {
property string title
TitleText {
size: 22
anchors.top: parent.top
}
TitleText {
size: 18
anchors.bottom: parent.bottom
}
}
// TitleText.qml
import QtQuick 2.0
Text {
property int size
text: "<b>" + title + "</b>"
font.pixelSize: size
}Dynamische Gültigkeitsbereiche sind sehr leistungsstark, müssen jedoch mit Bedacht eingesetzt werden, um zu verhindern, dass das Verhalten von QML-Code schwer vorhersehbar wird. Im Allgemeinen sollten sie nur in Fällen verwendet werden, in denen die beiden Komponenten bereits auf andere Weise eng miteinander gekoppelt sind. Beim Erstellen wiederverwendbarer Komponenten ist es vorzuziehen, Eigenschaftsschnittstellen wie folgt zu verwenden:
// TitlePage.qml
import QtQuick 2.0
Item {
id: root
property string title
TitleText {
title: root.title
size: 22
anchors.top: parent.top
}
TitleText {
title: root.title
size: 18
anchors.bottom: parent.bottom
}
}
// TitleText.qml
import QtQuick 2.0
Text {
property string title
property int size
text: "<b>" + title + "</b>"
font.pixelSize: size
}Verweisen Sie nicht von anderen QML-Komponenten aus auf das Stammobjekt „ id “
Vermeiden Sie den Zugriff auf die „ id “ eines Root-Objekts von außerhalb der QML-Datei, in der es definiert ist. „ id “-Werte sind nur innerhalb desselben Dokuments gültig, und der Zugriff darauf aus anderen Komponenten heraus verletzt die Kapselung und die Komponentengrenzen.
// Main.qml
import QtQuick
Item {
id: root
CustomItem { }
}
// CustomItem.qml
import QtQuick
Rectangle {
width: root.width
height: root.height / 2
color: "red"
}Im obigen Beispiel ist „ root “ nicht in „ CustomItem.qml “ deklariert. Der Code funktioniert dennoch, da „ CustomItem “ in einem Kontext instanziiert wird, in dem „ root “ existiert, was gemäß den Regeln für dynamische Gültigkeitsbereiche in QML zulässig ist. Dies führt jedoch zu einer impliziten Abhängigkeit vom äußeren Gültigkeitsbereich, wodurch die Komponente unzuverlässig wird und sich schwerer wiederverwenden lässt, wenn sie dynamisch geladen oder in einem anderen Kontext verwendet wird. Dieses Muster kann zudem zu subtilen Fehlern führen. Wenn beispielsweise ein anderes Objekt in der Gültigkeitsbereichskette denselben „ id “ verwendet, kann es das erwartete Objekt überschatten, was zu unerwartetem Verhalten führt.
Um Komponenten zuverlässig und wiederverwendbar zu machen, greifen Sie auf externe Zustände nur über explizite Eigenschaften, Eigenschaftsaliase oder Signale zu. Vermeiden Sie es, sich auf Werte von „ id “ im äußeren Geltungsbereich zu verlassen.
Das folgende Beispiel ersetzt dynamische Gültigkeitsbereiche durch eine explizite Komponenten-API.
// Main.qml
import QtQuick
import QtQuick.Window
Window {
id: root
width: 400
height: 300
visible: true
CustomItem {
width: root.width
height: root.height
boxColor: "blue"
}
}
// CustomItem.qml
import QtQuick
Item {
id: container
property alias boxColor: rect.color
Rectangle {
id: rect
width: container.width
height: container.height / 2
color: "red"
}
}Wenden Sie dieselbe Regel auf alle internen Objekte an, die innerhalb einer Komponente mit einem „ id “ deklariert sind.
// MyItem.qml
import QtQuick
Item {
Item {
id: internalCounter
property int count: 5
}
}
// main.qml
import QtQuick
MyItem {
Component.onCompleted: {
console.log(internalCounter.count);
}
}Im obigen Beispiel führt der Zugriff auf das id „ internalCounter “ aus einer anderen QML-Datei zu einem „ ReferenceError “, da ein „ id “ dokumentlokal ist und außerhalb der QML-Datei, in der es deklariert ist, nicht aufgerufen werden kann.
Wenn ein internes Objekt einen Zustand oder ein Verhalten offenlegen muss, sollten Sie dies explizit über Eigenschaften, Eigenschaftsaliase oder Signale tun.
Das folgende Beispiel macht den internen Zustand über eine explizite Komponenten-API zugänglich, anstatt auf den direkten Zugriff auf ein dokumentlokales ` id` zurückzugreifen.
// MyItem.qml
import QtQuick
Item {
Item {
id: internalCounter
property int count: 5
}
property alias internalCount: internalCounter.count
}
// main.qml
import QtQuick
MyItem {
Component.onCompleted: {
console.log(internalCount);
}
}Dies trägt zur Aufrechterhaltung klarer Komponentengrenzen bei und unterstützt eine bessere Skalierbarkeit und Testbarkeit.
Überschriebene Eigenschaften
QML erlaubt es, dass in einer Objektdeklaration definierte Eigenschaftsnamen durch Eigenschaften überschrieben werden, die in einer anderen Objektdeklaration deklariert sind, welche die erste erweitert. Zum Beispiel:
// Displayable.qml
import QtQuick 2.0
Item {
property string title
property string detail
Text {
text: "<b>" + title + "</b><br>" + detail
}
function getTitle() { return title }
function setTitle(newTitle) { title = newTitle }
}
// Person.qml
import QtQuick 2.0
Displayable {
property string title
property string firstName
property string lastName
function fullName() { return title + " " + firstName + " " + lastName }
}Hier wird der Name „ title “ sowohl der Überschrift des Ausgabetextes für „Displayable“ als auch dem Ehrentitel des „Person“-Objekts zugewiesen.
Eine überschriebene Eigenschaft wird entsprechend dem Geltungsbereich aufgelöst, in dem auf sie verwiesen wird. Innerhalb des Geltungsbereichs der „Person“-Komponente oder aus einem externen Geltungsbereich, der auf eine Instanz der „Person“-Komponente verweist, wird „ title “ auf die in „Person.qml“ deklarierte Eigenschaft aufgelöst. Die Funktion „ fullName “ verweist auf die in „Person.qml“ deklarierte Eigenschaft „ title “.
Innerhalb der „Displayable“-Komponente verweist „ title “ jedoch auf die in „Displayable.qml“ deklarierte Eigenschaft. Die Funktionen „getTitle()“ und „setTitle()“ sowie die Bindung für die Eigenschaft „ text “ des „Text“-Objekts verweisen alle auf die in der „Displayable“-Komponente deklarierte Eigenschaft „ title “.
Obwohl sie denselben Namen tragen, sind die beiden Eigenschaften völlig voneinander getrennt. Ein Signal-Handler „onChanged“ für eine der Eigenschaften wird nicht durch eine Änderung an der anderen Eigenschaft mit demselben Namen ausgelöst. Ein Alias für eine der beiden Eigenschaften verweist auf die eine oder die andere, aber nicht auf beide.
Globales JavaScript-Objekt
QML verbietet Typ-, ID- und Eigenschaftsnamen, die mit den Eigenschaften des globalen Objekts in Konflikt stehen, um Verwechslungen zu vermeiden. Programmierer können sich darauf verlassen, dass „ Math.min(10, 9) “ immer wie erwartet funktioniert!
Weitere Informationen finden Sie unter „JavaScript-Hostumgebung “.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.