Definieren von JavaScript-Ressourcen in QML

Die Programmlogik für eine QML-Anwendung kann in JavaScript definiert werden. Der JavaScript-Code kann entweder inline in QML-Dokumenten definiert oder in JavaScript-Dateien (in QML als JavaScript Resources bezeichnet) aufgeteilt werden.

Es gibt zwei verschiedene Arten von JavaScript-Ressourcen, die in QML unterstützt werden: Code-Behind-Implementierungsdateien und gemeinsam genutzte (Bibliotheks-)Dateien. Beide Arten von JavaScript-Ressourcen können von anderen JavaScript-Ressourcen importiert oder in QML-Module eingebunden werden.

Code-Behind-Implementierungsressource

Die meisten JavaScript-Dateien, die in ein QML-Dokument importiert werden, sind zustandsabhängige Implementierungen für das QML-Dokument, in das sie importiert werden. In diesen Fällen benötigt jede Instanz des im Dokument definierten QML-Objekttyps eine eigene Kopie der JavaScript-Objekte und des Zustands, um sich korrekt zu verhalten.

Das Standardverhalten beim Importieren von JavaScript-Dateien besteht darin, für jede QML-Komponenteninstanz eine eigene, isolierte Kopie bereitzustellen. Wenn diese JavaScript-Datei keine Ressourcen oder Module mit einer .import -Anweisung importiert, wird ihr Code im selben Bereich wie die QML-Komponenteninstanz ausgeführt und kann folglich auf die in dieser QML-Komponente deklarierten Objekte und Eigenschaften zugreifen und diese manipulieren. Andernfalls hat der Code seinen eigenen Bereich, und die Objekte und Eigenschaften der QML-Komponente sollten als Parameter an die Funktionen der JavaScript-Datei übergeben werden, wenn sie benötigt werden.

Es folgt ein Beispiel für eine Code-Behind-Implementierungsressource:

// MyButton.qml
import QtQuick 2.0
import "my_button_impl.js" as Logic // A new instance of this JavaScript resource
                                    // is loaded for each instance of Button.qml.

Rectangle {
    id: rect
    width: 200
    height: 100
    color: "red"

    MouseArea {
        id: mousearea
        anchors.fill: parent
        onClicked: Logic.onClicked(rect)
    }
}
// my_button_impl.js
var clickCount = 0;   // this state is separate for each instance of MyButton
function onClicked(button) {
    clickCount += 1;
    if ((clickCount % 5) == 0) {
        button.color = Qt.rgba(1,0,0,1);
    } else {
        button.color = Qt.rgba(0,1,0,1);
    }
}

Im Allgemeinen sollte einfache Logik inline in der QML-Datei definiert werden, komplexere Logik sollte jedoch aus Gründen der Wartbarkeit und Lesbarkeit in Code-Behind-Implementierungsressourcen aufgeteilt werden.

Gemeinsam genutzte JavaScript-Ressourcen (Bibliotheken)

Standardmäßig teilen die aus QML importierten JavaScript-Dateien ihren Kontext mit der QML-Komponente. Das bedeutet, dass die JavaScript-Dateien Zugriff auf dieselben QML-Objekte haben und diese verändern können. Infolgedessen muss jeder Import eine eindeutige Kopie dieser Dateien haben.

Der vorherige Abschnitt behandelt zustandsabhängige Importe von JavaScript-Dateien. Einige JavaScript-Dateien sind jedoch zustandslos und verhalten sich eher wie wiederverwendbare Bibliotheken in dem Sinne, dass sie eine Reihe von Hilfsfunktionen bereitstellen, die nichts von dem Ort benötigen, von dem sie importiert wurden. Sie können erhebliche Mengen an Speicherplatz sparen und die Instanziierung von QML-Komponenten beschleunigen, wenn Sie solche Bibliotheken mit einem speziellen Pragma markieren, wie im folgenden Beispiel gezeigt.

// factorial.js
.pragma library

var factorialCount = 0;

function factorial(a) {
    a = parseInt(a);

    // factorial recursion
    if (a > 0)
        return a * factorial(a - 1);

    // shared state
    factorialCount += 1;

    // recursion base-case.
    return 1;
}

function factorialCallCount() {
    return factorialCount;
}

Die pragma-Deklaration muss vor jeglichem JavaScript-Code erscheinen, Kommentare ausgenommen.

Beachten Sie, dass mehrere QML-Dokumente "factorial.js" importieren und die von ihr bereitgestellten Funktionen factorial und factorialCallCount aufrufen können. Der Status des JavaScript-Imports wird von allen QML-Dokumenten, die ihn importieren, gemeinsam genutzt, so dass der Rückgabewert der Funktion factorialCallCount ungleich Null sein kann, wenn er in einem QML-Dokument aufgerufen wird, das die Funktion factorial nie aufruft.

Ein Beispiel:

// Calculator.qml
import QtQuick 2.0
import "factorial.js" as FactorialCalculator // This JavaScript resource is only
                                             // ever loaded once by the engine,
                                             // even if multiple instances of
                                             // Calculator.qml are created.

Text {
    width: 500
    height: 100
    property int input: 17
    text: "The factorial of " + input + " is: " + FactorialCalculator.factorial(input)
}

Da sie gemeinsam genutzt werden, können .pragma-Bibliotheksdateien nicht direkt auf Instanzobjekte oder Eigenschaften von QML-Komponenten zugreifen, obwohl QML-Werte als Funktionsparameter übergeben werden können.

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