QT C++和HTML通信
摘要在QT中和HTML进行通信通过websocket转载请声明原创地址哟。PS:对这块不熟有错误请指出这换行有毒,谅解。概述: C++和HTML通过websocket通信,通过官方的qwebchannel.js实现。 C++和HTML共用一个对象并以此进行通信 C++通知HTML:通过信号 HTML通知C++:直接调用其函数 核心类:QWebChannel QT版本:5.6...
摘要
在QT中和HTML进行通信通过websocket
转载请声明原创地址哟。
PS:对这块不熟有错误请指出
这换行有毒,谅解。 
概述: C++和HTML通过websocket通信,通过官方的qwebchannel.js实现。 C++和HTML共用一个对象并以此进行通信 C++通知HTML:通过信号 HTML通知C++:直接调用其函数 核心类:QWebChannel QT版本:5.6
首先:例子是使用QT自带的例子 大致组成: WebSocketClientWrapper:一个包装为了将WebSocketTransport作为信号参数让QWebChannel能接受到 WebSocketTransport:关键点之一,继承自QWebChannelAbstractTransport Dialog:用于通信的对象 index.html:演示用的html文件 qwebchannel.js:关键点之一,本人是搜索了整个QT找出来的有3个同名文件大小有些区别,具体内容没看过有哪些区别,看目录也就应该知道选哪个了,没有的话运行会报错的,功能:类似管理吧,即存储着注册对象的方法,信号之类的,当然要处理收到的信息后才能存下来。
代码分析: PS:C++是服务端,HTML是客户端 本人:先把其他的大致看一下然后从main出发 main.cpp
-
#include "qwebchannel.h" -
#include <QApplication> -
#include <QDialog> -
#include <QVariantMap> -
#include <QDesktopServices> -
#include <QUrl> -
#include <QDir> -
#include <QFileInfo> -
#include <QtWebSockets/QWebSocketServer> -
#include "../shared/websocketclientwrapper.h" -
#include "../shared/websockettransport.h" -
#include "ui_dialog.h" -
class Dialog : public QObject -
{ -
Q_OBJECT -
public: -
explicit Dialog(QObject *parent = 0) -
: QObject(parent) -
{ -
ui.setupUi(&dialog); -
dialog.show(); -
connect(ui.send, SIGNAL(clicked()), SLOT(clicked())); -
} -
void displayMessage(const QString &message) -
{ -
ui.output->appendPlainText(message); -
} -
signals: -
void sendText(const QString &text); -
public slots: -
void receiveText(const QString &text) -
{ -
displayMessage(tr("Received message: %1").arg(text)); -
} -
private slots: -
void clicked() -
{ -
const QString text = ui.input->text(); -
if (text.isEmpty()) { -
return; -
} -
emit sendText(text); -
displayMessage(tr("Sent message: %1").arg(text)); -
ui.input->clear(); -
} -
private: -
QDialog dialog; -
Ui::Dialog ui; -
}; -
int main(int argc, char** argv) -
{ -
QApplication app(argc, argv); -
QFileInfo jsFileInfo(QDir::currentPath() + "/qwebchannel.js"); -
if (!jsFileInfo.exists()) -
QFile::copy(":/qtwebchannel/qwebchannel.js",jsFileInfo.absoluteFilePath()); -
//这只是为了能把qwebchannel.js放到指定目录能让index.html找到,在我这然并卵.手动复制 -
QWebSocketServer server(QStringLiteral("QWebChannel Standalone Example Server"), QWebSocketServer::NonSecureMode); -
//创建webSocket服务端,第二个参数应该是和关闭防火墙类似的操作,不进行安全检测 -
if (!server.listen(QHostAddress::LocalHost, 12345)) { -
qFatal("Failed to open web socket server."); -
return 1; -
} -
//创建完后肯定要绑定啦,地址端口号要和HTML中的一样 -
WebSocketClientWrapper clientWrapper(&server); -
/* 为了能将接受到的新连接的套接字包装成WebSocketTransport用信号传递给 -
** QWebChannel的void QWebChannel::connectTo(QWebChannelAbstractTransport *transport) -
** 而接受参数正好是QWebChannelAbstractTransport,WebSocketTransport就是它的子类 -
*/ -
QWebChannel channel; -
QObject::connect(&clientWrapper, &WebSocketClientWrapper::clientConnected, -
&channel, &QWebChannel::connectTo); -
/* -
** 当有新连接即html端打开,serve将获得与之相连的新socket,接着触发WebSocketClientWrapper槽 -
** 将socket作为WebSocketTransport参数实例化这个对象,然后作为信号参数传递给QWebChannel -
** QWebChannel就获得了与html通话的能力 -
*/ -
Dialog dialog; -
channel.registerObject(QStringLiteral("dialog"), &dialog);//注册后能在HTML中使用 -
//感觉就是这了,将Dialog的信号,函数等信息发给qwebchannel让其处理 -
QUrl url = QUrl::fromLocalFile(BUILD_DIR "/index.html"); -
QDesktopServices::openUrl(url); -
//这两句只是自动打开html而已,可以手动打开的哟 -
//为了照顾下面那一行代码才没有将其删除 -
dialog.displayMessage(QObject::tr("Initialization complete, opening browser at %1.").arg(url.toDisplayString())); -
return app.exec(); -
} -
#include "main.moc" -
/* -
* 一般情况下,你的类会单独写,一个 ***.h, 一个 ***.cpp 。 类的定义在 头文件中,qmake可以调用moc自动处理(生成moc_***.h)并自动包含。 -
但你要是偷懒,比如把main函数和类的定义及实现都放到一个文件内,比如取名 main.cpp ,这时就不那么走运了,moc处理后生成 同名 的 .moc 文件,但这时你必须自己包含它了。 -
*/
服务端小结: 1.准备serve,绑定地址端口 2.收到链接后交给QWebChannel 3.准备对象用于被注册(感觉随便啦,有信号,有方法就行)PS:应该是C++和HTML共用一个实例 只是C++是直接调用,HTML是通过QWebChannel调用
服务端暂时这样了,接下来看看客户端吧 index.html
-
<!DOCTYPE html> -
<html> -
<head> -
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> -
<script type="text/javascript" src="./qwebchannel.js"></script> -
<script type="text/javascript"> -
//BEGIN SETUP -
function output(message) -
{ -
var output = document.getElementById("output"); -
output.innerHTML = output.innerHTML + message + "\n"; -
} -
//为了在打印信息而准备的方法 -
window.onload = function() { -
if (location.search != "") -
var baseUrl = (/[?&]webChannelBaseUrl=([A-Za-z0-9\-:/\.]+)/.exec(location.search)[1]); -
else -
var baseUrl = "ws://localhost:12345"; -
output("Connecting to WebSocket server at " + baseUrl + "."); -
var socket = new WebSocket(baseUrl);//创建一个Socket实例,连接到服务器 -
//几个事件的绑定 -
socket.onclose = function() -
{ -
console.error("web channel closed"); -
}; -
socket.onerror = function(error) -
{ -
console.error("web channel error: " + error); -
}; -
socket.onopen = function()// 连接成功后触发 -
{ -
output("WebSocket connected, setting up QWebChannel."); -
//将socket交给qwebchannel.js,处理完后回调 -
new QWebChannel(socket, function(channel) { -
// make dialog object accessible globally -
window.dialog = channel.objects.dialog; -
//应该是设置全局对象吧,objects里应该就存放着注册的对象 -
document.getElementById("send").onclick = function() { -
var input = document.getElementById("input"); -
var text = input.value; -
if (!text) { -
return; -
} -
output("Sent message: " + text); -
input.value = ""; -
dialog.receiveText(text); -
} -
//HTML的send按钮的点击事件处理 -
dialog.sendText.connect(function(message) { -
output("Received message: " + message); -
}); -
//C++调用sendText时会使用到这里的匿名函数 -
dialog.receiveText("Client connected, ready to send/receive messages!"); -
//HTML直接调用函数 -
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 /> -
<input id="input" /><input type="submit" id="send" value="Send" onclick="javascript:click();" /> -
</body> -
</html>
客户端小结: 1.链接到服务器,并写好对应事件的绑定 2.new QWebChannel 3.qwebchannel.js会帮我们处理的
最后注意: 这些也是得有的在WebSocketTransport中
不要随便删。JSON也是要的传输的是JSON格式的数据
JS方面的能力比较渣,有错请喷,想深入了解的话可以去看源码,能力不足看晕了,不过这个qwebchannel.js倒是可以看一下,才400来行。 还是不太熟悉直接在参数里写函数,总觉得别扭,怪怪的。
FROM:https://my.oschina.net/LiangJYue/blog/668427
更多推荐


所有评论(0)