js與Qt通信

Qt WebChannel JavaScript API

設(shè)置 JavaScript API

要與QWebChannelWebChannel通信,客戶端必須使用并設(shè)置由qwebchannel.js. 對(duì)于在Qt WebEngine中運(yùn)行的客戶端,您可以通過qrc:///qtwebchannel/qwebchannel.js. 對(duì)于外部客戶端,您需要將文件復(fù)制到您的 Web 服務(wù)器。然后實(shí)例化一個(gè)QWebChannel對(duì)象并傳遞給它一個(gè)傳輸對(duì)象和一個(gè)回調(diào)函數(shù),一旦通道的初始化完成并且發(fā)布的對(duì)象變得可用,它們就會(huì)被調(diào)用。

傳輸對(duì)象實(shí)現(xiàn)了一個(gè)最小的消息傳遞接口。它應(yīng)該是一個(gè)帶有send()函數(shù)的對(duì)象,它接受一個(gè)字符串化的 JSON 消息并將其傳輸?shù)椒?wù)器端QWebChannelAbstractTransport對(duì)象。此外,onmessage當(dāng)收到來自服務(wù)器的消息時(shí),應(yīng)該調(diào)用它的屬性?;蛘?,您可以使用WebSocket來實(shí)現(xiàn)接口。

請(qǐng)注意,一旦傳輸對(duì)象完全可操作,就應(yīng)該構(gòu)造JavaScript QWebChannel對(duì)象。對(duì)于 WebSocket,這意味著您應(yīng)該在套接字的處理程序中創(chuàng)建QWebChannelonopen。查看Qt WebChannel Standalone Example以了解這是如何完成的。

與 QObject 交互

一旦調(diào)用了傳遞給QWebChannel對(duì)象的回調(diào),通道就完成了初始化,HTML 客戶端可以通過該channel.objects屬性訪問所有發(fā)布的對(duì)象。因此,假設(shè)一個(gè)對(duì)象是使用標(biāo)識(shí)符“foo”發(fā)布的,那么我們可以與它進(jìn)行交互,如下例所示。請(qǐng)注意,HTML 客戶端和 QML/C++ 服務(wù)器之間的所有通信都是異步的。屬性緩存在 HTML 端。此外請(qǐng)記住,只有可以轉(zhuǎn)換為 JSON 的 QML/C++ 數(shù)據(jù)類型才能正確(反)序列化,從而可供 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.onMyPropertyChanged.connect(function(newValue) {
          console.log(newValue);
      });
 
      // One can also access enums that are marked with Q_ENUM:
      console.log(foo.MyEnum.MyEnumerator);
  });

重載的方法和信號(hào)

當(dāng)您發(fā)布QObject具有重載方法的方法時(shí),QWebChannel會(huì)將方法調(diào)用解析為最佳匹配。請(qǐng)注意,由于 JavaScript 的類型系統(tǒng),只有一個(gè)“數(shù)字”類型最適合映射到 C++“double”。當(dāng)重載僅在類數(shù)字參數(shù)的類型上有所不同時(shí),QWebChannel將始終選擇最匹配 JavaScript 'number' 類型的重載。當(dāng)您連接到重載信號(hào)時(shí),QWebChannel客戶端默認(rèn)情況下將僅連接到該名稱的第一個(gè)重載信號(hào)。此外,方法和信號(hào)的重載可以通過它們的完整QMetaMethod簽名明確地請(qǐng)求。QObject假設(shè)我們?cè)?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 端與這個(gè)類進(jìn)行交互:

 // 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)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 您好!歡迎加入Qt MOOC! 本主題涵蓋了您在學(xué)習(xí)本課程時(shí)所需的大部分基本知識(shí)。我們將從課程的角度,以練習(xí)的形式...
    amos_56fc閱讀 756評(píng)論 0 0
  • Qt的模塊主要包含四大部分,分別是 Qt基礎(chǔ)模塊 Qt附加模塊 Qt增值模塊 Qt Tools其中,基礎(chǔ)模塊和附加...
    秋冬不寒閱讀 904評(píng)論 0 2
  • QML 性能上的注意事項(xiàng)和建議 趙者也[http://www.itdecent.cn/u/7b2ff27d6fd...
    趙者也閱讀 16,674評(píng)論 1 11
  • 界面 主窗口界面設(shè)計(jì) 標(biāo)題欄:直接設(shè)Window-Title屬性;Window-icon屬性可加圖標(biāo)。底部狀態(tài)欄:...
    碼園老農(nóng)閱讀 3,969評(píng)論 1 13
  • 1. Qt串口通信類QSerialPort 在Qt5的的更新中,新增了串口通信的相關(guān)接口類QSerialPort,...
    Jiatian閱讀 4,499評(píng)論 0 5

友情鏈接更多精彩內(nèi)容