JavaScript-Ausdrücke in QML-Dokumenten

Die von QML bereitgestellte JavaScript-Host-Umgebung kann gültige Standard-JavaScript-Konstrukte wie bedingte Operatoren, Arrays, das Setzen von Variablen und Schleifen ausführen. Zusätzlich zu den Standard-JavaScript-Eigenschaften enthält das QML Global Object eine Reihe von Hilfsmethoden, die die Erstellung von Benutzeroberflächen und die Interaktion mit der QML-Umgebung vereinfachen.

Die von QML bereitgestellte JavaScript-Umgebung ist strikter als die eines Webbrowsers. So können Sie in QML beispielsweise keine Elemente des globalen JavaScript-Objekts hinzufügen oder ändern. In normalem JavaScript ist es möglich, dies versehentlich zu tun, indem man eine Variable verwendet, ohne sie zu deklarieren. In QML führt dies zu einer Ausnahme, so dass alle lokalen Variablen explizit deklariert werden müssen. Eine vollständige Beschreibung der Einschränkungen für JavaScript-Code, der von QML aus ausgeführt wird, finden Sie unter JavaScript-Umgebungseinschränkungen.

Verschiedene Teile von QML-Dokumenten können JavaScript-Code enthalten:

  1. Der Body von Property Bindings. Diese JavaScript-Ausdrücke beschreiben Beziehungen zwischen QML-Objekteigenschaften. Wenn sich die Abhängigkeiten einer Eigenschaft ändern, wird auch die Eigenschaft automatisch aktualisiert, entsprechend der angegebenen Beziehung.
  2. Der Hauptteil der Signal-Handler. Diese JavaScript-Anweisungen werden automatisch ausgewertet, wenn ein QML-Objekt das zugehörige Signal aussendet.
  3. Die Definition von benutzerdefinierten Methoden. JavaScript-Funktionen, die im Body eines QML-Objekts definiert sind, werden zu Methoden dieses Objekts.
  4. Eigenständige JavaScript-Ressourcendateien (.js). Diese Dateien sind eigentlich von QML-Dokumenten getrennt, können aber in QML-Dokumente importiert werden. Funktionen und Variablen, die in den importierten Dateien definiert sind, können in Property-Bindings, Signal-Handlern und benutzerdefinierten Methoden verwendet werden.

JavaScript in Eigenschaftsbindungen

Im folgenden Beispiel ist die Eigenschaft color von Rectangle abhängig von der Eigenschaft pressed von TapHandler. Diese Beziehung wird durch einen bedingten Ausdruck beschrieben:

import QtQuick 2.12

Rectangle {
    id: colorbutton
    width: 200; height: 80;

    color: inputHandler.pressed ? "steelblue" : "lightsteelblue"

    TapHandler {
        id: inputHandler
    }
}

Eigentlich kann jeder JavaScript-Ausdruck (egal wie komplex) in einer Property-Binding-Definition verwendet werden, solange das Ergebnis des Ausdrucks ein Wert ist, dessen Typ der Property zugewiesen werden kann. Dies gilt auch für Seiteneffekte. Von komplexen Bindungen und Seiteneffekten wird jedoch abgeraten, da sie die Leistung, Lesbarkeit und Wartbarkeit des Codes beeinträchtigen können.

Es gibt zwei Möglichkeiten, eine Eigenschaftsbindung zu definieren: Die gängigste ist die im Beispiel oben gezeigte, in einer Eigenschaftsinitialisierung. Die zweite (und viel seltenere) Möglichkeit besteht darin, der Eigenschaft eine Funktion zuzuweisen, die von der Funktion Qt.binding() zurückgegeben wird, und zwar innerhalb von imperativem JavaScript-Code, wie unten gezeigt:

import QtQuick 2.12

Rectangle {
    id: colorbutton
    width: 200; height: 80;

    color: "red"

    TapHandler {
        id: inputHandler
    }

    Component.onCompleted: {
        color = Qt.binding(function() { return inputHandler.pressed ? "steelblue" : "lightsteelblue" });
    }
}

Weitere Informationen zur Definition von Property-Bindings finden Sie in der Dokumentation zu Property-Bindings, und in der Dokumentation zu Property Assignment versus Property Binding erfahren Sie, wie sich Property-Bindings von Wertzuweisungen unterscheiden.

JavaScript in Signalhandlern

QML-Objekttypen können als Reaktion auf das Eintreten bestimmter Ereignisse Signale aussenden. Diese Signale können von Signal-Handler-Funktionen verarbeitet werden, die von Clients definiert werden können, um benutzerdefinierte Programmlogik zu implementieren.

Angenommen, eine Schaltfläche vom Typ Rechteck hat eine TapHandler und eine Textbeschriftung. Die TapHandler gibt ihr Signal tapped aus, wenn der Benutzer die Schaltfläche drückt. Die Clients können auf das Signal im onTapped Handler mit JavaScript-Ausdrücken reagieren. Die QML-Engine führt diese im Handler definierten JavaScript-Ausdrücke nach Bedarf aus. Normalerweise ist ein Signal-Handler an JavaScript-Ausdrücke gebunden, um andere Ereignisse auszulösen oder Eigenschaftswerte zuzuweisen.

import QtQuick 2.12

Rectangle {
    id: button
    width: 200; height: 80; color: "lightsteelblue"

    TapHandler {
        id: inputHandler
        onTapped: {
            // arbitrary JavaScript expression
            console.log("Tapped!")
        }
    }

    Text {
        id: label
        anchors.centerIn: parent
        text: inputHandler.pressed ? "Pressed!" : "Press here!"
    }
}

Weitere Einzelheiten zu Signalen und Signal-Handlern finden Sie in den folgenden Themen:

JavaScript in Standalone-Funktionen

Programmlogik kann auch in JavaScript-Funktionen definiert werden. Diese Funktionen können inline in QML-Dokumenten (als eigene Methoden) oder extern in importierten JavaScript-Dateien definiert werden.

JavaScript in benutzerdefinierten Methoden

Benutzerdefinierte Methoden können in QML-Dokumenten definiert werden und von Signalhandlern, Eigenschaftsbindungen oder Funktionen in anderen QML-Objekten aufgerufen werden. Solche Methoden werden oft als Inline-JavaScript-Funktionen bezeichnet, da ihre Implementierung in der QML-Objekttypdefinition (QML-Dokument) enthalten ist und nicht in einer externen JavaScript-Datei.

Ein Beispiel für eine benutzerdefinierte Inline-Methode lautet wie folgt:

import QtQuick 2.12

Item {
    function fibonacci(n){
        var arr = [0, 1];
        for (var i = 2; i < n + 1; i++)
            arr.push(arr[i - 2] + arr[i -1]);

        return arr;
    }
    TapHandler {
        onTapped: console.log(fibonacci(10))
    }
}

Die Fibonacci-Funktion wird immer dann ausgeführt, wenn TapHandler ein tapped Signal sendet.

Hinweis: Die benutzerdefinierten Methoden, die inline in einem QML-Dokument definiert sind, sind anderen Objekten zugänglich, und daher können Inline-Funktionen auf dem Root-Objekt in einer QML-Komponente von Anrufern außerhalb der Komponente aufgerufen werden. Wenn dies nicht erwünscht ist, kann die Methode einem Nicht-Root-Objekt hinzugefügt oder vorzugsweise in eine externe JavaScript-Datei geschrieben werden.

Weitere Informationen zur Definition von benutzerdefinierten Methoden in QML mit JavaScript finden Sie in der Dokumentation QML-Objektattribute.

In einer JavaScript-Datei definierte Funktionen

Nicht-triviale Programmlogik wird am besten in eine separate JavaScript-Datei ausgelagert. Diese Datei kann mit einer import -Anweisung in QML importiert werden, wie die QML-Module.

Die Methode fibonacci() aus dem vorangegangenen Beispiel könnte beispielsweise in eine externe Datei mit dem Namen fib.js ausgelagert und wie folgt aufgerufen werden:

import QtQuick 2.12
import "fib.js" as MathFunctions

Item {
    TapHandler {
        onTapped: console.log(MathFunctions.fibonacci(10))
    }
}

Weitere Informationen zum Laden externer JavaScript-Dateien in QML finden Sie im Abschnitt über den Import von JavaScript-Ressourcen in QML.

Verbinden von Signalen mit JavaScript-Funktionen

QML-Objekttypen, die Signale ausgeben, bieten auch Standard-Signalhandler für ihre Signale, wie im vorherigen Abschnitt beschrieben. Manchmal möchte ein Client jedoch eine in einem QML-Objekt definierte Funktion auslösen, wenn ein anderes QML-Objekt ein Signal aussendet. Solche Szenarien können über eine Signalverbindung abgewickelt werden.

Ein von einem QML-Objekt ausgegebenes Signal kann mit einer JavaScript-Funktion verbunden werden, indem die Methode connect() des Signals aufgerufen und die JavaScript-Funktion als Argument übergeben wird. Der folgende Code verbindet zum Beispiel das Signal tapped von TapHandler mit dem Signal jsFunction() in script.js:

import QtQuick
import "script.js" as MyScript

Item {
    id: item
    width: 200; height: 200

    TapHandler {
        id: inputHandler
    }

    Component.onCompleted: {
        inputHandler.tapped.connect(MyScript.jsFunction)
    }
}
// script.js

function jsFunction() {
    console.log("Called JavaScript function!")
}

Das Signal jsFunction() wird immer dann aufgerufen, wenn das Signal tapped von TapHandler ausgegeben wird.

Weitere Informationen finden Sie unter Verbinden von Signalen mit Methoden und Signalen.

JavaScript im Startcode der Anwendung

Gelegentlich ist es notwendig, beim Starten einer Anwendung (oder Komponenteninstanz) zwingenden Code auszuführen. Es ist zwar verlockend, das Startskript einfach als globalen Code in eine externe Skriptdatei einzubinden, doch kann dies zu erheblichen Einschränkungen führen, da die QML-Umgebung möglicherweise noch nicht vollständig eingerichtet ist. Zum Beispiel könnten einige Objekte noch nicht erstellt oder einige Eigenschaftsbindungen noch nicht hergestellt worden sein. Die genauen Beschränkungen von globalem Skriptcode finden Sie unter JavaScript-Umgebungseinschränkungen.

Ein QML-Objekt gibt das Signal Component.completed attached aus, wenn seine Instanziierung abgeschlossen ist. Der JavaScript-Code im entsprechenden Component.onCompleted -Handler wird ausgeführt, nachdem das Objekt instanziiert wurde. Daher ist der beste Ort, um Code für den Anwendungsstart zu schreiben, der Component.onCompleted -Handler des Top-Level-Objekts, denn dieses Objekt sendet Component.completed, wenn die QML-Umgebung vollständig eingerichtet ist.

Ein Beispiel:

import QtQuick 2.0

Rectangle {
    function startupFunction() {
        // ... startup code
    }

    Component.onCompleted: startupFunction();
}

Jedes Objekt in einer QML-Datei - einschließlich verschachtelter Objekte und verschachtelter QML-Komponenteninstanzen - kann diese angehängte Eigenschaft verwenden. Wenn es mehr als einen onCompleted() Handler gibt, der beim Start ausgeführt werden muss, werden sie nacheinander in einer nicht definierten Reihenfolge ausgeführt.

Ebenso gibt jedes Component ein destruction()-Signal aus, kurz bevor es zerstört wird.

© 2025 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.