Auf dieser Seite

Qt WebChannel JavaScript-API

Einrichten der JavaScript-API

Um mit QWebChannel oder WebChannel zu kommunizieren, muss ein Client die von qwebchannel.js bereitgestellte JavaScript-API verwenden und einrichten. Für Clients, die innerhalb von Qt WebEngine, können Sie die Datei über qrc:///qtwebchannel/qwebchannel.js laden, wenn Sie die Seite lokal aufrufen, oder qwebchannel.js über eine bei QWebEngineUrlScheme als QWebEngineUrlScheme::SecureScheme registrierte QWebEngineUrlSchemeHandler zugänglich machen. Für externe Clients müssen Sie die Datei auf Ihren Webserver kopieren. Instanziieren Sie anschließend ein ` QWebChannel `-Objekt und übergeben Sie ihm ein Transportobjekt sowie eine Callback-Funktion, die aufgerufen wird, sobald die Initialisierung des Kanals abgeschlossen ist und die veröffentlichten Objekte verfügbar sind. Ein optionales drittes Argument enthält ein Array von Konverter-Wrapper-Funktionen oder eine einzelne davon.

Das Transportobjekt implementiert eine minimale Schnittstelle zur Nachrichtenübermittlung. Es sollte ein Objekt mit einer ` send() `-Funktion sein, die eine als String dargestellte JSON-Nachricht entgegennimmt und an das serverseitige ` QWebChannelAbstractTransport `-Objekt überträgt. Darüber hinaus sollte seine Eigenschaft ` onmessage ` aufgerufen werden, wenn eine Nachricht vom Server empfangen wurde. Alternativ können Sie ein WebSocket verwenden, um die Schnittstelle zu implementieren.

Beachten Sie, dass das JavaScript-Objekt ` QWebChannel ` erst erstellt werden sollte, sobald das Transportobjekt voll funktionsfähig ist. Im Falle eines WebSockets bedeutet dies, dass Sie das ` QWebChannel ` im ` onopen `-Handler des Sockets erstellen sollten. Sehen Sie sich das eigenständige Beispiel „Qt WebChannel “ an, um zu erfahren, wie dies umgesetzt wird.

Hinweis: Pro Transport darf auf derselben Seitenur ein einziges „ QWebChannel “-Objekt erstellt werden.

Eine Konverter-Wrapper-Funktion ist entweder eine Zeichenkette mit dem Namen eines integrierten Konverters oder eine vom Benutzer bereitgestellte Funktion, die das zu verarbeitende Objekt als Argument entgegennimmt und den resultierenden Typ zurückgibt – oder „undefined“, falls die Funktion nicht anwendbar ist. Wird „undefined“ zurückgegeben, wird der nächste Konverter verarbeitet. Gibt es keine Konverter, die einen anderen Wert als „undefined“ zurückgeben, wird die Verarbeitung wie gewohnt fortgesetzt. „Date“ ist derzeit die einzige integrierte Konverterfunktion. Sie nimmt eine Zeichenkette mit einem Datum im ISO-8601-Format entgegen und gibt ein neues „Date“-Objekt zurück, sofern die Syntax korrekt und das Datum gültig ist.

Interaktion mit QObjects

Sobald der an das ` QWebChannel `-Objekt übergebene Callback aufgerufen wird, hat der Kanal die Initialisierung abgeschlossen und alle veröffentlichten Objekte sind für den HTML-Client über die Eigenschaft ` channel.objects ` zugänglich. Angenommen, ein Objekt wurde mit der Kennung „foo“ veröffentlicht, dann können wir wie im folgenden Beispiel gezeigt mit ihm interagieren. Beachten Sie, dass die gesamte Kommunikation zwischen dem HTML-Client und dem QML/C++-Server asynchron erfolgt. Eigenschaften werden auf der HTML-Seite zwischengespeichert. Beachten Sie außerdem, dass nur QML/C++-Datentypen, die in JSON konvertiert werden können, ordnungsgemäß (de-)serialisiert werden und somit für HTML-Clients zugänglich sind.

new QWebChannel(yourTransport, function(channel) {

    // Connect to a signal:
    channel.objects.foo.mySignal.connect(function() {
        // This callback will be invoked whenever the signal is emitted on the C++/QML side.
        console.log(arguments);
    });

    // To make the object known globally, assign it to the window object, i.e.:
    window.foo = channel.objects.foo;

    // Invoke a method:
    foo.myMethod(arg1, arg2, function(returnValue) {
        // This callback will be invoked when myMethod has a return value. Keep in mind that
        // the communication is asynchronous, hence the need for this callback.
        console.log(returnValue);
    });

    // Read a property value, which is cached on the client side:
    console.log(foo.myProperty);

    // Writing a property will instantly update the client side cache.
    // The remote end will be notified about the change asynchronously
    foo.myProperty = "Hello World!";

    // To get notified about remote property changes,
    // simply connect to the corresponding notify signal:
    foo.myPropertyChanged.connect(function() {
        console.log(foo.myProperty);
    });

    // One can also access enums that are marked with Q_ENUM:
    console.log(foo.MyEnum.MyEnumerator);
});

Überladene Methoden und Signale

Wenn Sie ein „ QObject “ veröffentlichen, das überladene Methoden enthält, ordnet „ QWebChannel “ Methodenaufrufe der am besten passenden Methode zu. Beachten Sie, dass es aufgrund des Typsystems von JavaScript nur einen einzigen „number“-Typ gibt, der am besten einem C++-„double“ entspricht. Wenn sich Überladungen nur im Typ eines zahlähnlichen Parameters unterscheiden, wählt „ QWebChannel “ immer die Überladung aus, die am besten zum JavaScript-Typ „number“ passt. Wenn Sie eine Verbindung zu einem überladenen Signal herstellen, verbindet sich der „ QWebChannel “-Client standardmäßig nur mit der ersten Signalüberladung dieses Namens. Zusätzlich können Überladungen von Methoden und Signalen explizit über ihre vollständige „ QMetaMethod “-Signatur angefordert werden. Nehmen wir an, wir haben auf der C++-Seite die folgende Unterklasse „ QObject “:

class Foo : public QObject
{
    Q_OBJECT
slots:
    void foo(int i);
    void foo(double d);
    void foo(const QString &str);
    void foo(const QString &str, int i);

signals:
    void bar(int i);
    void bar(const QString &str);
    void bar(const QString &str, int i);
};

Dann können Sie auf der JavaScript-Seite wie folgt mit dieser Klasse interagieren:

// methods
foo.foo(42); // will call the method named foo which best matches the JavaScript number parameter, i.e. foo(double d)
foo.foo("asdf"); // will call foo(const QString &str)
foo.foo("asdf", 42); // will call foo(const QString &str, int i)
foo["foo(int)"](42); // explicitly call foo(int i), *not* foo(double d)
foo["foo(QString)"]("asdf"); // explicitly call foo(const QString &str)
foo["foo(QString,int)"]("asdf", 42); // explicitly call foo(const QString &str, int i)

// signals
foo.bar.connect(...); // connect to first signal named bar, i.e. bar(int i)
foo["bar(int)"].connect(...); // connect explicitly to bar(int i)
foo["bar(QString)"].connect(...); // connect explicitly to bar(const QString &str)
foo["bar(QString,int)"].connect(...); // connect explicitly to bar(const QString &str, int i)

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