要通信與
QWebChannel
or
WebChannel
,客戶端必須使用和設置 JavaScript API 提供通過
qwebchannel.js
。若客戶端運行在
Qt WebEngine
,可以加載文件通過
qrc:///qtwebchannel/qwebchannel.js
。對於外部客戶端,需要將文件拷貝到 Web 服務器。 然後實例化
QWebChannel
object and pass it a transport object and a callback function, which will be invoked once the initialization of the channel finishes and the published objects become available. An optional third argument contains an array of converter wrapper functions or a single one.
傳輸對象實現最少消息傳遞接口。它應是對象且具有
send()
函數,其接受字符串化 JSON 消息,並將消息傳輸到服務器側
QWebChannelAbstractTransport
對象。此外,它的
onmessage
特性應被調用,當從自服務器收到消息時。另外,可以使用
WebSocket
去實現接口。
注意:JavaScript
QWebChannel
對象應該被構造一旦傳輸對象可完整操作。對於 WebSocket,意味著應該創建
QWebChannel
在套接字的
onopen
處理程序。查看
Qt WebChannel 獨立範例
看如何做到這點。
A converter wrapper function is either a string with the name of a built-in converter or a user supplied function that takes the object to process as an argument and returns the resultant type or undefined if the function does not apply. If undefined is returned the next converter is processed. If there are no converters that returns a value other than undefined, processing proceeds as normal. "Date" is the only currently built-in converter function. It takes a string with an ISO 8601 date and returns a new Date object if the syntax is right and the date is valid.
一旦迴調傳遞給
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 的類型係統,隻有單 number 類型能最好映射到 C++ double。當重載僅在像 number 參數的類型上有所不同時,
QWebChannel
將始終選取最佳匹配 JavaScript number 類型的重載。當連接到被重載信號時,
QWebChannel
默認情況下,客戶端隻會連接到該名稱的第一信號重載。此外,可以明確請求方法和信號的重載通過其完整
QMetaMethod
簽名。假定有以下
QObject
子類在 C++ 側:
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)