In qt5.15 qml how to deal with Native Function Exposure and JavaScript-to-Native Communication(caling a native function) using qml Webview

70 views Asked by At

So I am using qt5.15.3 with qml and trying to handle Native Function Exposure and JavaScript-to-Native Communication

First I need to clarify my question For example like in Java we have:

// In your WebView setup code
WebView webView = findViewById(R.id.webView);
NativeInterface nativeInterface = new NativeInterface();
webView.addJavascriptInterface(nativeInterface, "NativeInterface");

NativeInterface class:

public class NativeInterface {
    @JavascriptInterface
    public void CANBUS_Write(String id,String[] data) {
        // Call the native CANBUS_Write function here with the provided data
    }
}

In webpage side we got something like:

function CANBUS_Write(id, data) {
    window.NativeInterface.CANBUS_Write(id, data);
}

to handle Native Function Exposure and JavaScript-to-Native Communication

How to deal with the same question in qt5 qml using WebView?

import QtWebView 1.1

 WebView {
 id:webView
 anchors.fill: parent
 url: "http://192.168.120.56:8888/test"


}

What I have tried

ServerSideHandler.h

#ifndef SERVERSIDEHANDLER_H
#define SERVERSIDEHANDLER_H



#include <QObject>
#include <QStringList>

class ServerSideHandler : public QObject
{
    Q_OBJECT
public:
    explicit ServerSideHandler(QObject *parent = nullptr);

public slots:
    void CANBUS_Write(const QString &ID, const QStringList &data);
};

#endif // SERVERSIDEHANDLER_H

ServerSideHandler.cpp

#include "serversidehandler.h"
#include <QDebug>

ServerSideHandler::ServerSideHandler(QObject *parent) : QObject(parent)
{
        qDebug() <<"Init";
}

void ServerSideHandler::CANBUS_Write(const QString &ID, const QStringList &data)
{
    QStringList sBuffer;
    for (const QString &item : data) {
        sBuffer.append(item);
    }
    qDebug() << "CANBUS_Write ID" << ID << ", data =" << sBuffer.join(' ');
}

main.cpp

qmlRegisterType<ServerSideHandler>("ServerSideHandler", 1, 0, "ServerSideHandler");

main.qml

 ServerSideHandler{
        id :server

    }

    WebView {
        id:webView
        anchors.fill: parent
       
        url: "http://192.168.120.56:8888/test"
        
        Component.onCompleted: {
 
            channel.registerObject("NativeInterface",server);
        }
   
        WebChannel{
            id: channel

        }
   
    }
1

There are 1 answers

0
jason yu On BEST ANSWER

OK I think I solve the problem it is not that complicated actually just directly inject into the webpage

   webView.runJavaScript(`
                          // Define a global object to expose functions
                          var NativeInterface= {
                          CANBUS_Write: function(ID, data) {  
                          return { id: ID, dataArray: data };
                          }
                          };
                          `);

and also write a callback to show result while reading the result

  webView.runJavaScript(`
       NativeInterface.CANBUS_Write('123', ['data1', 'data2', 'data3'])
                                  `, function(result) {
    console.log("JavaScript NativeInterfaceresult:", JSON.stringify(result));
});