说明
在使用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 += core gui webenginewidgets
mainwindows.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtWebChannel/QtWebChannel> //包含头文件
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
#include <QMainWindow>
class QWebChannel;
class QPushButton;
class QLineEdit;
class QTextEdit;
class WebChannelObject;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
private slots://槽函数
void sendMessage();//发送消息
void receiveMessage(const QString &message);//接受消息
private:
void setupUi();
void setupWebChannel();
private:
QPushButton *sendButton;
QLineEdit *messageEdit;
QTextEdit *messageList;
QWebChannel *webChannel;
WebChannelObject *webChannelObject;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "webchannelobject.h"
#include <QtWidgets>
#include <QtWebChannel/QtWebChannel>
#include <QtWebEngineWidgets/QWebEngineView>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setupUi();
setupWebChannel();
//参数1 发出者 参数2是发出什么时触发 参数3 接收者 参数4 接收者怎么处理
connect(sendButton, &QPushButton::clicked, this, &MainWindow::sendMessage);//信号和槽对应
}
void MainWindow::sendMessage()
{
QString message = messageEdit->text();
// 将消息发送到JavaScript
webChannelObject->sendMessageToJS(message);
// 在Qt界面上显示发送的消息
messageList->append("You: " + message);
messageEdit->clear();
}
void MainWindow::receiveMessage(const QString &message)
{
// 在Qt界面上显示接收的消息
messageList->append("Friend: " + message);
}
void MainWindow::setupUi()
{
QWidget *centralWidget = new QWidget;
QVBoxLayout *layout = new QVBoxLayout;
sendButton = new QPushButton("Send");
messageEdit = new QLineEdit;
messageList = new QTextEdit;
messageList->setReadOnly(true);
layout->addWidget(messageList);
layout->addWidget(messageEdit);
layout->addWidget(sendButton);
centralWidget->setLayout(layout);
setCentralWidget(centralWidget);
}
void MainWindow::setupWebChannel()
{
QWebEngineView *webView = new QWebEngineView;
webChannel = new QWebChannel(this);
webView->page()->setWebChannel(webChannel);
webView->setUrl(QUrl::fromLocalFile(qApp->applicationDirPath()+"/index.html")); // 加载HTML文件
setCentralWidget(webView);
// 创建一个对象用于Qt和JavaScript通信
webChannelObject = new WebChannelObject;
webChannel->registerObject(QStringLiteral("webChannelObject"), webChannelObject);
}
webchannelobject.h
#ifndef WEBCHANNELOBJECT_H
#define WEBCHANNELOBJECT_H
#include <QObject>
class WebChannelObject : public QObject
{
Q_OBJECT
public:
WebChannelObject(QObject *parent = nullptr);
signals:
void messageReceived(const QString &message);
public slots:
void sendMessageToJS(const QString &message);
};
#endif // WEBCHANNELOBJECT_H
webchannelobject.cpp
#include "webchannelobject.h"
WebChannelObject::WebChannelObject(QObject *parent) : QObject(parent) {}
void WebChannelObject::sendMessageToJS(const QString &message)
{
emit messageReceived(message);
}
main.cpp
#include "mainwindow.h
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
index.html
<!DOCTYPE html>
<html>
<head>
<script src="E:\work\exercise\QtWebChannelAndJavaScript\qwebchannel.js"></script>
<script>
var webChannel;
// 当页面加载完成时初始化WebChannel
document.addEventListener("DOMContentLoaded", function () {
new QWebChannel(qt.webChannelTransport, function (channel) {
//对应于webChannel->registerObject(QStringLiteral("webChannelObject"),webChannelObject);
webChannel = channel.objects.webChannelObject;
// 监听Qt发来的消息
webChannel.messageReceived.connect(function (message) {
showMessage(message);
});
});
});
function showMessage(message) {
var messageList = document.getElementById("messageList");
var p = document.createElement("p");
p.textContent = "Friend: " + message;
messageList.appendChild(p);
}
function sendMessage() {
var messageInput = document.getElementById("messageInput");
var message = messageInput.value;
// 将消息发送到Qt
webChannel.sendMessageToJS(message);
// 在Web界面上显示发送的消息
var messageList = document.getElementById("messageList");
var p = document.createElement("p");
p.textContent = "You: " + message;
messageList.appendChild(p);
// 清空输入框
messageInput.value = "";
}
</script>
</head>
<body>
<h1>Qt and JavaScript Chat Example</h1>
<div id="messageList"></div>
<input type="text" id="messageInput" placeholder="Enter your message..." />
<button onclick="sendMessage()">Send</button>
</body>
</html>
其他的通信模块
-
QtWebKit:
作用:QtWebKit是一个用于在Qt应用程序中嵌入Web内容的模块,类似于Qt WebEngine。它基于Webkit引擎,支持JavaScript与C++的交互。用法:您可以使用QtWebKit将Web页面嵌入到Qt应用程序中,并使用类似QJSEngine的方法来实现JavaScript与C++之间的通信。
-
Qt QML和Qt Quick:
作用:Qt QML是一种用于创建用户界面的声明性语言,而Qt Quick是一个用于创建现代、动态和流畅用户界面的技术。它允许在Qt应用程序中使用JavaScript来定义界面和逻辑,并与C++进行交互。用法:您可以在Qt Quick中使用JavaScript定义用户界面,并通过信号和槽机制或C++对象暴露给JavaScript进行交互。
-
WebSocket通信:
作用:WebSocket是一种在Web浏览器和服务器之间进行双向通信的技术,也可以用于在Qt应用程序和Web页面之间进行通信。用法:您可以在Qt应用程序和Web页面中分别实现WebSocket客户端和服务器,通过WebSocket协议进行双向通信,传递数据和命令。
-
QtDBus:
作用:QtDBus是一个用于在不同进程之间进行通信的模块,可以用于实现C++和JavaScript之间的通信,尤其是在不同进程中的情况下。用法:您可以使用QtDBus来定义接口和信号,然后在C++和JavaScript之间进行通信和数据传递。
-
WebSockets和REST API:
作用:WebSockets和REST API是用于在Web应用程序和服务器之间进行通信的标准技术。您可以在Qt应用程序和Web页面中分别实现WebSocket通信或通过REST API进行数据交换。 -
基于消息队列的通信:
作用:您可以使用消息队列,如ZeroMQ、RabbitMQ等,来在Qt应用程序和Web页面之间进行异步通信。用法:通过将消息发送到消息队列,然后在另一侧进行监听和处理,可以实现C++和JavaScript之间的通信。