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