QWebChannel实现与JS的交互

QWebChannel实现与JS的交互

在利用Qt框架的QWebEngineView进行嵌入浏览器开发时,可以很方便的通过

QWebChannel实现与js的交互,本节内容简单讲解js与Qt应用程序相互发送消息。

最近做项目遇到了这个问题,发现网上的例子不全,很多都是单向通讯。自己实现了这部分,简单记录一下

在使用Qt(C++)和JavaScript之间实现通信时,通常会使用一些模块和技术来使两者能够交互和传递数据。这种通信通常用于在Qt应用程序中嵌入Web内容,或者在Web页面中嵌入Qt应用程序。以下是一些常用的模块和技术,以及它们的作用

Qt WebEngine模块:

作用:Qt WebEngine是Qt中的Web引擎,允许在Qt应用程序中嵌入Web内容,包括JavaScript脚 本。它基于Chromium,提供了一个完整的Web浏览器引擎。

用法:您可以使用Qt WebEngine将Web页面嵌入到Qt应用程序中,并通过JavaScript与应用程序进行通信。这可以通过JavaScript和C++之间的信号和槽机制来实现。

Qt QWebChannel模块:

作用:QWebChannel是一个用于在Qt和JavaScript之间进行通信的模块。它使Qt中的C++对象能够通过WebSocket与嵌入在Web页面中的JavaScript进行通信。

用法:您可以使用QWebChannel在Qt应用程序和Web页面之间传递数据和调用函数。这样,您可以在Qt中暴露C++对象,使其可以在JavaScript中访问,反之亦然。

Qt QJSEngine模块:

作用:QJSEngine是一个用于在Qt应用程序中执行JavaScript代码的模块。它允许您在C++中嵌入JavaScript,并在两者之间交换数据。

用法:您可以使用QJSEngine在Qt应用程序中执行JavaScript代码,并通过QJSEngine来访问C++对象和数据。这在需要动态执行和控制JavaScript代码的情况下很有用。

JavaScript与C++交互的桥接技术:

作用:除了上述Qt提供的模块,还可以使用其他桥接技术来实现JavaScript与C++之间的通信,如Embind、Boost.JS等。这些技术允许在C++和JavaScript之间创建双向的函数调用和数据传递。

用法:您可以使用这些技术将C++函数暴露给JavaScript调用,并在C++中调用JavaScript函数。这样可以实现更紧密的集成和通信。

pro文件加入模块引用

QT += webenginewidgets webchannel

MyProjectWidget.h

#pragma once
#include <QWebEngineView>
#include <QtWebChannel>
#include <QtWidgets/QWidget>
#include <QPushButton>
#include "WebClass.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MyProjectWidget; }
QT_END_NAMESPACE

class MyProjectWebView;

class MyProjectWidget : public QWidget {
    Q_OBJECT

public:
    explicit MyProjectWidget(QWidget *parent = nullptr);
    ~MyProjectWidget() override;

public Q_SLOTS:
    void sendToJS();
    void receiveFromJS(const QString &data);

private:
    Ui::MyProjectWidget *ui;
    QPushButton *button;
    QWebEngineView *webView = nullptr;
    QWebChannel *webChannel = nullptr;
    QWebEngineView *m_consoleView = nullptr;

    WebClass *webobj;

    int numer = 0;
};

MyProjectWidget.cpp

#include "MyProjectWidget.h"
#include "ui_MyProjectWidget.h"
#include <QtCore/QSysInfo>
#include <QtCore/qglobal.h>
#include <QtNetwork/QHostInfo>
#include "MyProjectWebView.h"
#include <QShortcut>


MyProjectWidget::MyProjectWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MyProjectWidget) {
    ui->setupUi(this);

    button = new QPushButton ("Send Message to JavaScript");

    webView = new QWebEngineView(parent);
#ifdef QT_DEBUG

    // F12 调试窗口
    QShortcut* shortcut = new QShortcut(QKeySequence(Qt::Key_F12), this);
    setShortcutEnabled(shortcut->id(), true);
    QObject::connect(shortcut, &QShortcut::activated, this, [&]() mutable {
        if (m_consoleView == nullptr)
            m_consoleView = new QWebEngineView();

        webView->page()->setDevToolsPage(m_consoleView->page());
        webView->page()->triggerAction(QWebEnginePage::InspectElement);
        m_consoleView->show();
    });
#endif // QT_DEBUG

    //webView->load(QStringLiteral("qrc:/index.html"));
    webView->load(QUrl::fromLocalFile("F:\test_qt\js\data\index.html"));

    ui->vLayMain->addWidget(button);
    ui->vLayMain->addWidget(webView);


    webChannel = new QWebChannel;
    webobj = new WebClass();
    webChannel->registerObject("webobj", webobj);
    webView->page()->setWebChannel(webChannel);

    QObject::connect(button, &QPushButton::clicked, this, &MyProjectWidget::sendToJS);

    QObject::connect(webobj, &WebClass::strDataChanged, this, &MyProjectWidget::receiveFromJS);
}

MyProjectWidget::~MyProjectWidget() {
    delete ui;
}

void MyProjectWidget::sendToJS()
{
    QString numberstr = QString::number(numer++);
    QJsonObject json;
    json["key1"] = "https://kfb-dc-store.obs.cn-east-2.myhuaweicloud.com/123.xls";
    numberstr = QString::number(numer++);
    json["key2"] = "https://kfb-dc-store.obs.cn-east-2.myhuaweicloud.com/577.xls";
    webobj->setProperty("jsonData", json);
}

void MyProjectWidget::receiveFromJS(const QString &data)
{
    qDebug() << "receiveFromJS:" << data;

    QByteArray parameterArray = data.toUtf8();
    QJsonDocument jsonDocument = QJsonDocument::fromJson(parameterArray);

    qDebug() << "jsonDocument:" << jsonDocument;
}

WebClass.h

#pragma once

#include <QtCore/QObject>
#include <QJsonObject>
#include <QMessageBox>

class WebClass : public QObject {
    Q_OBJECT
    Q_PROPERTY(QJsonObject jsonData MEMBER m_jsonData NOTIFY dataChanged)
    Q_PROPERTY(QString m_data MEMBER m_data NOTIFY strDataChanged)

public:
    WebClass(QObject* parent = nullptr){};
    ~WebClass() override {};

signals:
    void dataChanged(const QJsonObject &jsonData);
    void strDataChanged(const QString &data);
private:
    QJsonObject m_jsonData;
    QString m_data;
};

main.cpp

#include <QApplication>
#include <QDesktopServices>
#include <QWebEnginePage>
#include <QWebEngineProfile>
#include <QWebEngineView>
#include "MyProjectWidget.h"
int main(int argc, char *argv[])
{
    QCoreApplication::setOrganizationName("QtExamples");
    QApplication app(argc, argv);
    MyProjectWidget myProject;
    myProject.show();
    return app.exec();
}

index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta charset="utf-8">
    <!-- 引入 ECharts 文件 -->
    <script src="F:/test_qt/js/data/echarts.min.js"></script>
    <title>Fetch JSON Example</title>
</head>
<p id="x">x:</p>
<p id="y">y:</p>
<body>
    <script src="qwebchannel.js"></script>
    <script type="text/javascript">
    var webobj;
        new QWebChannel(qt.webChannelTransport, function (channel) {
                webobj = channel.objects.webobj;
                webobj.dataChanged.connect(function (arg) {
                    console.log(arg.key1);
                    x.innerHTML = arg.key1;
                    y.innerHTML = arg.key2;
                });
            });

        function sendMessageToQt() {
            console.log("12354");
            const json = JSON.stringify({ key: 'value' ,age: "30", city: "New York"});
            webobj.m_data = json;
        }
    </script>
  <button onclick="sendMessageToQt()">Send Message to qt</button>
</body>
</html>

这样就实现了qt和H5的json对象传递了。

相关推荐
夏天的味道٥2 小时前
使用 Java 执行 SQL 语句和存储过程
java·开发语言·sql
Fantasywt3 小时前
THREEJS 片元着色器实现更自然的呼吸灯效果
前端·javascript·着色器
IT、木易3 小时前
大白话JavaScript实现一个函数,将字符串中的每个单词首字母大写。
开发语言·前端·javascript·ecmascript
冰糖码奇朵4 小时前
大数据表高效导入导出解决方案,mysql数据库LOAD DATA命令和INTO OUTFILE命令详解
java·数据库·sql·mysql
好教员好4 小时前
【Spring】整合【SpringMVC】
java·spring
Mr.NickJJ4 小时前
JavaScript系列06-深入理解 JavaScript 事件系统:从原生事件到 React 合成事件
开发语言·javascript·react.js
浪九天5 小时前
Java直通车系列13【Spring MVC】(Spring MVC常用注解)
java·后端·spring
堕落年代5 小时前
Maven匹配机制和仓库库设置
java·maven
功德+n6 小时前
Maven 使用指南:基础 + 进阶 + 高级用法
java·开发语言·maven
念九_ysl6 小时前
深入解析Vue3单文件组件:原理、场景与实战
前端·javascript·vue.js