You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Qt5.15 QML WebView实现Native函数暴露与JS-Native通信

实现Qt WebEngineView与网页JS的Native函数调用(类似Java addJavascriptInterface)

需求说明

使用Qt5.15.3结合QML开发,需要实现类似Java WebView中addJavascriptInterface的功能:将Native端的函数暴露给网页,让网页中的JavaScript可以直接调用Native方法完成交互。

Java实现参考示例

WebView初始化代码

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

NativeInterface类

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

网页端调用代码

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

本人尝试的Qt代码

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. 项目配置修正

首先确保.pro文件中添加必要的Qt模块支持:

QT += core gui qml quick webengine webchannel

SOURCES += \
    main.cpp \
    ServerSideHandler.cpp

HEADERS += \
    ServerSideHandler.h

RESOURCES += qml.qrc

2. QML代码修正(替换为WebEngineView)

Qt的WebView(QtWebView模块)封装原生系统WebView,不支持WebChannel;需使用WebEngineView(QtWebEngine模块)实现通信:

import QtQuick 2.15
import QtQuick.Window 2.15
import QtWebEngine 1.15
import ServerSideHandler 1.0

Window {
    width: 800
    height: 600
    visible: true
    title: qsTr("WebChannel Demo")

    ServerSideHandler {
        id: server
    }

    WebEngineView {
        id: webEngineView
        anchors.fill: parent
        url: "http://192.168.120.56:8888/test"

        // 将WebChannel与WebEngineView绑定
        webChannel: channel

        WebChannel {
            id: channel
            Component.onCompleted: {
                // 注册Native对象到WebChannel,名称为"NativeInterface"
                registerObject("NativeInterface", server)
            }
        }
    }
}

3. 网页端代码适配

网页需要引入Qt官方提供的qwebchannel.js文件(可从Qt安装目录Qt5.15.3/5.15.3/[编译器]/lib/QtWebChannel.5.15.3/resources/qwebchannel.js获取),并通过WebChannel建立连接:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Test Page</title>
    <!-- 引入qwebchannel.js,确保路径正确 -->
    <script src="qwebchannel.js"></script>
</head>
<body>
    <button onclick="testCallNative()">调用Native CANBUS函数</button>

    <script>
        let nativeInterface;

        // 初始化WebChannel连接
        new QWebChannel(qt.webChannelTransport, function(channel) {
            // 获取Native端注册的对象
            nativeInterface = channel.objects.NativeInterface;
        });

        function CANBUS_Write(id, data) {
            if (nativeInterface) {
                nativeInterface.CANBUS_Write(id, data);
            }
        }

        // 测试调用函数
        function testCallNative() {
            CANBUS_Write("0x123", ["0x01", "0x02", "0x03"]);
        }
    </script>
</body>
</html>

关键注意事项

  • qwebchannel.js必须正确加载:可放置在网页同目录,或打包到Qt资源文件中通过资源路径访问。
  • 参数类型兼容:Qt的QString对应JS字符串,QStringList对应JS数组,基本类型会自动完成转换。
  • 确保WebChannel与WebEngineView正确绑定:必须通过webChannel属性关联,否则无法建立通信。

内容的提问来源于stack exchange,提问作者jason yu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 03:57:06