QT:⽤QWebSocket实现webchannel,实现C++与HTML通信基本原理是通过channel将C++对象暴露给HTML,在HTML中调⽤qwebchannel.js。前提是建⽴transport,QT只提供了⼀个抽象基类QWebChannelAbstractTransport,需要⾃⼰进⾏实现,官⽅建议⽤QWebSocket实现,并给出了实例。
1、实现Transport类,内置⼀个WebSocket套接字;
2、实现新的channel类,内置⼀个WebSocketServer;
3、利⽤新的channel注册C++对象,从⽽HTML可以使⽤该对象;
4、通过以下三种⽅式进⾏C++与HTML的交互:
4.1 在HTML中l连接C++ signal与js函数的
t(function(){});
4.2 在HTML中调⽤C++ public slots函数;
4.3 在HTML中调⽤C++ Q_INVOKABLE修饰的函数;
下⾯给出实例代码
5.1 WebSocketTransport类
websockettransport.h
1 #ifndef WEBSOCKETTRANSPORT_H
2#define WEBSOCKETTRANSPORT_H
3
4 #include <QWebChannelAbstractTransport>
5
6 QT_BEGIN_NAMESPACE
7class QWebSocket;
8 QT_END_NAMESPACE
9
10class WebSocketTransport : public QWebChannelAbstractTransport
11 {
12    Q_OBJECT
13public:
14explicit WebSocketTransport(QWebSocket *socket);
15virtual ~WebSocketTransport();
16
17void sendMessage(const QJsonObject &message) override;
18
19private slots:
20void textMessageReceived(const QString &message);
21
22private:
23    QWebSocket *m_socket;
24 };
25
26#endif// WEBSOCKETTRANSPORT_H
websockettransport.cpp
1 #include "websockettransport.h"
2
3 #include <QDebug>
4 #include <QJsonDocument>
5 #include <QJsonObject>
6 #include <QWebSocket>
7
8
9/*!
10    Construct the transport object and wrap the given socket.
11
12    The socket is also set as the parent of the transport object.
13*/
14 WebSocketTransport::WebSocketTransport(QWebSocket *socket)
15 : QWebChannelAbstractTransport(socket)
16 , m_socket(socket)
17 {
18    connect(socket, &QWebSocket::textMessageReceived,
19this, &WebSocketTransport::textMessageReceived);
20    connect(socket, &QWebSocket::disconnected,
21this, &WebSocketTransport::deleteLater);
22 }
23
24/*!
25    Destroys the WebSocketTransport.
26*/
27 WebSocketTransport::~WebSocketTransport()
28 {
29    m_socket->deleteLater();
30 }
31
32/*!
33    Serialize the JSON message and send it as a text message via the WebSocket to the client. 34*/
35void WebSocketTransport::sendMessage(const QJsonObject &message)
36 {
37    QJsonDocument doc(message);
38    m_socket->sendTextMessage(QString::Json(QJsonDocument::Compact)));
39 }
40
41/*!
42    Deserialize the stringified JSON messageData and emit messageReceived.
43*/
44void WebSocketTransport::textMessageReceived(const QString &messageData)
45 {
46    QJsonParseError error;
47    QJsonDocument message = QJsonDocument::Utf8(), &error);
48if () {
49        qWarning() << "Failed to parse text message as JSON object:" << messageData
50                    << "Error is:" << String();
51return;
52    } else if (!message.isObject()) {
53        qWarning() << "Received JSON message that is not an object: " << messageData;
54return;
55    }
56    emit messageReceived(message.object(), this);
57 }
5.2 WebSocketChannel类
websocketchannel.h
#ifndef WEBSOCKETCHANNEL_H
#define WEBSOCKETCHANNEL_H
#include <QWebChannel>
class QWebSocketServer;
class WebSocketTransport;
//继承QWebchannel类,在内部建⽴socket server与transport中socket的连接
class WebSocketChannel : public QWebChannel
{
Q_OBJECT
public:
WebSocketChannel(QWebSocketServer *server);
signals:
void clientConnected(WebSocketTransport *client);
private slots:
void handleNewConnection();
private:
QWebSocketServer *_server;
};
#endif// WEBSOCKETCHANNEL_H
websocketchannel.cpp
#include "websocketchannel.h"
#include <QWebSocketServer>
#include "websockettransport.h"
WebSocketChannel::WebSocketChannel(QWebSocketServer *server)
:_server(server)
{
connect(server, &QWebSocketServer::newConnection,
this, &WebSocketChannel::handleNewConnection);
connect(this, &WebSocketChannel::clientConnected,
this, &WebSocketChannel::connectTo);//connectTo槽继承⾃QWebchannel
}
void WebSocketChannel::handleNewConnection()
{
emit clientConnected(new WebSocketTransport(_server->nextPendingConnection()));
}
main.cpp
#include <QApplication>
#include <QDesktopServices>
#include <QDialog>
#include <QDir>
#include <QFileInfo>
#include <QUrl>
#include <QWebChannel>
#include <QWebSocketServer>
int main(int argc, char** argv)
{
QApplication app(argc, argv);
//建⽴QWebSocketServer,url是ws://localhost:12345
QWebSocketServer server(QStringLiteral("QWebChannel Standalone Example Server"), QWebSocketServer::NonSecureMode); if (!server.listen(QHostAddress::LocalHost, 12345)) {
qFatal("Failed to open web socket server.");
return1;
}
//建⽴websocketchannl,该channel就可以⽤来通信了
WebSocketChannel channel(&server);
// setup the UI
Dialog dialog;
// setup the core and publish it to the QWebChannel
Core core(&dialog);
//注册C++对象,该类要继承⾃QObject
// open a browser window with the client HTML page
QUrl url = QUrl::fromLocalFile(BUILD_DIR "/index.html");
QDesktopServices::openUrl(url);
dialog.displayMessage(Dialog::tr("Initialization complete, opening browser at %1.").DisplayString()));
dialog.show();
();
}
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
//使⽤qwebchannel.js
<script type="text/javascript" src="./qwebchannel.js"></script>
<script type="text/javascript">
//BEGIN SETUP
function output(message) {
var output = ElementById("output");
output.innerHTML = output.innerHTML + message + "\n";
}
var baseUrl = "ws://localhost:12345";
output("Connecting to WebSocket server at " + baseUrl + ".");
var socket = new WebSocket(baseUrl);
<("web channel closed");
};
<("web channel error: " + error);
};
output("WebSocket connected, setting up QWebChannel.");
new QWebChannel(socket, function(channel) {
// make core object accessible globally
< = ;
var input = ElementById("input");
var text = input.value;
if (!text) {
return;
}
output("Sent message: " + text);
input.value = "";
//调⽤C++公有槽函数
core.hello(text);
}
//连接C++信号与javascript函数
t(function(message) {
output("Received message: " + message);
});
output("Connected to WebChannel, ready to send/receive messages!");
});
}
}
//END SETUP
</script>
<style type="text/css">
html {
height: 100%;
width: 100%;
}
#input {
width: 400px;
margin: 0 10px 0 0;
}
#send {
width: 90px;
margin: 0;
}
#output {
width: 500px;
height: 300px;
}
</style>
</head>
<body>
<textarea id="output"></textarea><br />
websocket和socket<input id="input"/><input type="submit" id="send" value="Send" onclick="javascript:click();"/> </body>
</html>
结果如下:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。