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

  • 24
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QWebChannel是一个用于在Qt应用程序和Web页面中进行双向通信的桥梁。在这种情况下,Qt应用程序可以通过QWebChannel将其对象暴露给JavaScript,以便JavaScript可以调用其方法和访问其属性。反过来,JavaScript也可以将其对象暴露给Qt应用程序,以便Qt应用程序可以调用其方法和访问其属性。这种双向通信可以用于在Qt应用程序和Web页面之间传递数据和事件,从而实现更紧密的集成。 以下是使用QWebChannelQtJavaScript之间进行交互的基本步骤: 1. 在Qt应用程序中创建一个QWebChannel对象,并将其绑定到一个QWidget或QWebEngineView对象上。例如: ``` QWebChannel *channel = new QWebChannel(this); channel->registerObject("myObject", myObject); ui->webView->page()->setWebChannel(channel); ``` 其中,myObject是Qt应用程序中的一个QObject派生类的实例,它包含可以从JavaScript中调用的方法和属性。 2. 在Web页面中创建一个QWebChannel对象,并将其连接到Qt应用程序中的QWebChannel对象。例如: ``` var channel = new QWebChannel(); channel.registerObject("myObject", myObject); ``` 其中,myObject是JavaScript中的一个对象,它包含可以从Qt应用程序中调用的方法和属性。 3. 在Web页面中使用QWebChannel对象来调用Qt应用程序中的方法或访问其属性。例如: ``` channel.objects.myObject.myMethod(); var value = channel.objects.myObject.myProperty; ``` 其中,myMethod是Qt应用程序中的一个方法,myProperty是Qt应用程序中的一个属性。 4. 在Qt应用程序中使用QWebChannel对象来调用JavaScript中的方法或访问其属性。例如: ``` QWebChannel *channel = ui->webView->page()->webChannel(); QVariant result; channel->evaluateJavaScript("myObject.myMethod()", &result); qDebug() << result.toString(); ``` 其中,myMethod是JavaScript中的一个方法。evaluateJavaScript方法用于在Web页面中执行JavaScript代码,并返回结果。在本例中,结果将存储在result变量中并输出到控制台。 通过上述步骤,Qt应用程序和JavaScript之间可以进行双向通信,并共享数据和事件。这种集成可以用于实现许多不同的应用程序,例如将Qt应用程序嵌入到Web页面中,或将Web内容嵌入到Qt应用程序中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值