Qt WebChannel JavaScript API

JavaScript API のセットアップ

QWebChannel またはWebChannel と通信するためには、クライアントはqwebchannel.js が提供する JavaScript API を使用してセットアップする必要があります。Qt WebEngine 内で実行されるクライアントの場合、qrc:///qtwebchannel/qwebchannel.js からファイルを読み込むことができます。外部クライアントの場合は、ファイルを Web サーバーにコピーする必要があります。次に、QWebChannel オブジェクトをインスタンス化し、トランスポートオブジェクトとコールバック関数を渡します。この関数は、チャネルの初期化が終了し、公開オブジェクトが利用可能になった時点で呼び出されます。オプションの第3引数には、コンバーターラッパー関数の配列、または単一の関数が含まれる。

トランスポートオブジェクトは最小限のメッセージパッシングインターフェースを実装します。これは、文字列化されたJSONメッセージを受け取り、サーバー側のQWebChannelAbstractTransport オブジェクトに送信するsend() 関数を持つオブジェクトでなければなりません。さらに、サーバーからのメッセージを受信すると、onmessage プロパティが呼び出されます。あるいは、WebSocketを使ってこのインタフェースを実装することもできます。

JavaScriptのQWebChannel オブジェクトは、トランスポートオブジェクトが完全に動作するようになってから構築する必要があることに注意してください。WebSocket の場合は、ソケットのonopen ハンドラでQWebChannel を作成する必要があります。Qt WebChannel Standalone Exampleを参照してください。

注意: 同じページに作成できるのは、1つのトランスポートにつき1つのQWebChannel オブジェクトだけです。

コンバーターラッパー関数は、組み込みコンバーターの名前を持つ文字列か、ユーザーが提供する関数で、処理するオブジェクトを引数として取り、結果の型を返すか、関数が適用されない場合は未定義を返します。undefinedが返された場合は、次のコンバータが処理される。undefined 以外の値を返すコンバータがない場合、処理は通常どおり進められます。"Date "は現在唯一の組み込みコンバータ関数です。ISO 8601の日付文字列を受け取り、構文が正しく日付が有効であれば新しいDateオブジェクトを返します。

Qオブジェクトとの対話

QWebChannel オブジェクトに渡されたコールバックが呼び出されると、チャネルの初期化が終了し、すべての発行オブジェクトはchannel.objects プロパティ経由で HTML クライアントからアクセスできるようになります。したがって、あるオブジェクトが識別子 "foo "でパブリッシュされたと仮定すると、以下の例に示すように、そのオブジェクトと対話することができます。なお、HTMLクライアントとQML/C++サーバー間の通信はすべて非同期です。プロパティはHTML側にキャッシュされます。さらに、JSONに変換可能なQML/C++のデータ型のみが正しく(デ)シリアライズされ、HTMLクライアントからアクセスできることに留意してください。

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);
});

オーバーロードされたメソッドとシグナル

オーバーロードされたメソッドを持つQObject を公開すると、QWebChannel はメソッドの呼び出しを最適なものに解決します。JavaScriptの型システムのため、C++の'double'に最もよく対応する単一の'number'型しかないことに注意してください。オーバーロードが数値のようなパラメータの型でのみ異なる場合、QWebChannel は常に、JavaScript の 'number' 型に最もマッチするオーバーロードを選択します。オーバーロードされたシグナルに接続すると、QWebChannel クライアントはデフォルトで、その名前の最初のシグナル・オーバーロードにのみ接続します。さらに、メソッドやシグナルのオーバーロードは、QMetaMethod シグネチャの完全な形で明示的に要求することができます。C++側に以下の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);
};

JavaScript側では、このクラスを次のように操作できます:

// 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)

本書に含まれる文書の著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。