Qt WebChannel JavaScript API
设置 JavaScript API
要与QWebChannel 或WebChannel 通信,客户端必须使用和设置qwebchannel.js
提供的 JavaScript API。对于在 Qt WebEngine可以通过qrc:///qtwebchannel/qwebchannel.js
加载文件。对于外部客户端,则需要将文件复制到网络服务器上。然后实例化一个QWebChannel 对象,并传递给它一个传输对象和一个回调函数,一旦通道初始化完成且发布的对象可用,就会调用该回调函数。可选的第三个参数包含一个转换器封装函数数组或一个转换器封装函数。
传输对象实现了一个最小的消息传递接口。它应该是一个带有send()
函数的对象,该函数接收字符串化的 JSON 消息并将其传输到服务器端QWebChannelAbstractTransport 对象。此外,当收到来自服务器的消息时,应调用其onmessage
属性。或者,也可以使用WebSocket来实现该接口。
需要注意的是,JavaScriptQWebChannel 对象应在传输对象完全运行后构建。如果是 WebSocket,这意味着应在套接字的onopen
处理程序中创建QWebChannel 。请查看Qt WebChannel Standalone 示例,了解如何实现这一点。
注意: 在同一个页面中,每个传输只能创建一个QWebChannel
对象。
转换器封装函数是一个包含内置转换器名称的字符串,或者是一个用户提供的函数,它将要处理的对象作为参数,并返回结果类型,如果函数不适用,则返回未定义。如果返回未定义,则处理下一个转换器。如果没有转换器返回未定义值以外的值,则按正常方式处理。"日期 "是目前唯一的内置转换器函数。它接收一个包含 ISO 8601 日期的字符串,如果语法正确且日期有效,则返回一个新的日期对象。
与 QObjects 交互
一旦传给QWebChannel 对象的回调被调用,通道就完成了初始化,HTML 客户端可通过channel.objects
属性访问所有已发布的对象。因此,假设发布了一个标识符为 "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 "最匹配。当重载仅在类数字参数的类型上存在差异时,QWebChannel 将始终选择与 JavaScript "数字 "类型最匹配的重载。连接到重载信号时,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)
© 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.