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

cpp 复制代码
#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

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

cpp 复制代码
#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

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

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对象传递了。

相关推荐
abiao19813 分钟前
VUE的“单向数据绑定” 和 “双向数据绑定”
前端·javascript·vue.js
LoveDreaMing11 分钟前
微前端-无界的实操和源码分析
前端·javascript·架构
修炼前端秘籍的小帅15 分钟前
精读《JavaScript 高级程序设计 第4版》第6章 集合引用类型(三)Map、WeakMap、Set、WeakSet
开发语言·javascript·ecmascript
十八朵郁金香36 分钟前
【H5工具】一个简约高级感渐变海报H5设计工具
前端·javascript·产品运营·axure·个人开发
lkbhua莱克瓦2438 分钟前
Java基础——常用API2
java·笔记·github·学习方法
拉不动的猪1 小时前
多窗口数据实时同步常规方案举例
前端·javascript·vue.js
摇滚侠1 小时前
Spring Boot3零基础教程,Lambda 表达式与函数式接口,笔记95
java·spring boot·笔记
好学且牛逼的马1 小时前
【JavaWeb|day19 Web后端进阶 SpringAOP、SpringBoot原理、自定义Starter、Maven高级】
java·spring boot·rpc
码界奇点1 小时前
Java 开发日记MySQL 与 Redis 双写一致性策略挑战与实战解析
java·redis·sql·mysql·java-ee
GHZero1 小时前
Java 之解读String源码(九)
java·开发语言