QT:用QWebSocket实现webchannel,实现C++与HTML通信
1、实现Transport类,内置一个WebSocket套接字;
2、实现新的channel类,内置一个WebSocketServer;
3、利用新的channel注册C++对象,从而HTML可以使用该对象;
4、通过以下三种方式进行C++与HTML的交互:
4.1 在HTML中l连接C++ signal与js函数的
object.signal.connect(function(){});
4.2 在HTML中调用C++ public slots函数;
4.3 在HTML中调用C++ Q_INVOKABLE修饰的函数;
5.1 WebSocketTransport类
websockettransport.h
#ifndef WEBSOCKETTRANSPORT_H
#define WEBSOCKETTRANSPORT_H #include <QWebChannelAbstractTransport> QT_BEGIN_NAMESPACE
class QWebSocket;
QT_END_NAMESPACE class WebSocketTransport : public QWebChannelAbstractTransport
{
Q_OBJECT
public:
explicit WebSocketTransport(QWebSocket *socket);
virtual ~WebSocketTransport(); void sendMessage(const QJsonObject &message) override; private slots:
void textMessageReceived(const QString &message); private:
QWebSocket *m_socket;
}; #endif // WEBSOCKETTRANSPORT_H
websockettransport.cpp
#include "websockettransport.h" #include <QDebug>
#include <QJsonDocument>
#include <QJsonObject>
#include <QWebSocket> /*!
Construct the transport object and wrap the given socket. The socket is also set as the parent of the transport object.
*/
WebSocketTransport::WebSocketTransport(QWebSocket *socket)
: QWebChannelAbstractTransport(socket)
, m_socket(socket)
{
connect(socket, &QWebSocket::textMessageReceived,
this, &WebSocketTransport::textMessageReceived);
connect(socket, &QWebSocket::disconnected,
this, &WebSocketTransport::deleteLater);
} /*!
Destroys the WebSocketTransport.
*/
WebSocketTransport::~WebSocketTransport()
{
m_socket->deleteLater();
} /*!
Serialize the JSON message and send it as a text message via the WebSocket to the client.
*/
void WebSocketTransport::sendMessage(const QJsonObject &message)
{
QJsonDocument doc(message);
m_socket->sendTextMessage(QString::fromUtf8(doc.toJson(QJsonDocument::Compact)));
} /*!
Deserialize the stringified JSON messageData and emit messageReceived.
*/
void WebSocketTransport::textMessageReceived(const QString &messageData)
{
QJsonParseError error;
QJsonDocument message = QJsonDocument::fromJson(messageData.toUtf8(), &error);
if (error.error) {
qWarning() << "Failed to parse text message as JSON object:" << messageData
<< "Error is:" << error.errorString();
return;
} else if (!message.isObject()) {
qWarning() << "Received JSON message that is not an object: " << messageData;
return;
}
emit messageReceived(message.object(), this);
}
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
#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, )) {
qFatal("Failed to open web socket server.");
return ;
} //建立websocketchannl,该channel就可以用来通信了
WebSocketChannel channel(&server); // setup the UI
Dialog dialog; // setup the core and publish it to the QWebChannel
Core core(&dialog); //注册C++对象,该类要继承自QObject
channel.registerObject(QStringLiteral("core"), &core); // 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.").arg(url.toDisplayString()));
dialog.show(); return app.exec();
}
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 = document.getElementById("output");
output.innerHTML = output.innerHTML + message + "\n";
}
window.onload = function() {
var baseUrl = "ws://localhost:12345"; output("Connecting to WebSocket server at " + baseUrl + ".");
var socket = new WebSocket(baseUrl); 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.");
new QWebChannel(socket, function(channel) {
// make core object accessible globally
window.core = channel.objects.core; document.getElementById("send").onclick = function() {
var input = document.getElementById("input");
var text = input.value;
if (!text) {
return;
} output("Sent message: " + text);
input.value = ""; //调用C++公有槽函数
core.receiveText(text);
core.hello(text);
} //连接C++信号与javascript函数
core.sendText.connect(function(message) {
output("Received message: " + message);
}); core.receiveText("Client connected, ready to send/receive messages!");
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>
结果如下:
QT:用QWebSocket实现webchannel,实现C++与HTML通信的更多相关文章
- [转]QT子线程与主线程的信号槽通信-亲测可用!
近用QT做一个服务器,众所周知,QT的主线程必须保持畅通,才能刷新UI.所以,网络通信端采用新开线程的方式.在涉及到使用子线程更新Ui上的控件时遇到了点儿麻烦.网上提供了很多同一线程不同类间采用信号槽 ...
- QT网络编程UDP下C/S架构广播通信
QT有封装好的UDP协议的类,QUdpSocket,里面有我们想要的函数接口.感兴趣的话,可以看看. 先搞服务端吧,写一个子类,继承QDialog类,起名为UdpServer类.头文件要引用我们上边说 ...
- QT实现OPC_UA客户端程序以及与OPC_UA服务器通信
1.OPC_UA服务器准备工作 1.关于OPC_UA服务器的搭建可以参考前面一篇文章:https://blog.csdn.net/xipengbozai/article/details/1150809 ...
- 通过WebChannel/WebSockets与QML中的HTML交互
来源:通过WebChannel/WebSockets与QML中的HTML交互 GitHub:八至 作者:狐狸家的鱼 本文链接:QML与HTML交互 在查询QML与HTML之间通信交互时资料很少,这篇文 ...
- Qt的QWebChannel和JS、HTML通信/交互驱动百度地图
Qt的QWebChannel和JS.HTML通信/交互驱动百度地图 0 前言 我一个研究嵌入式的,不知道怎么就迷上了上位机,接了几个项目都是关于Qt,这个项目还是比较经典的,自己没事儿的时候也进行研究 ...
- 如何才能学到Qt的精髓——信号槽之间的无关性,提供了绝佳的对象间通讯方式,QT的GUI全是自己的一套,并且完全开源,提供了一个绝好机会窥视gui具体实现
姚冬,中老年程序员 叶韵.KY Xu.赵奋强 等人赞同 被邀请了很久了,一直在思考,今天终于下决心开始写回答. 这个问题的确是够大的,Qt的代码规模在整个开源世界里也是名列前茅的,这么大的项目其中的精 ...
- QT中C++与Html端通信例子
C++(服务端)和HTML(客户端)通过websocket通信,通过qwebchannel.js实现 C++ -> HTML,通过信号. HTML -> C++,直接调用函数. Main函 ...
- Qt笔记——元对象系统
Qt元对象系统提供了对象间的通信机制:信号和槽.以及执行类形信息和动态属性系统的支持.是标注C++的一个扩展,它使得Qt可以更好的实现GUI图形用户界面编程.Qt的元对象系统不支持C++模板.虽然模板 ...
- Qt配置USBCAN通信
周立功为CAN通信提供了动态库:官方提供了很多相关动态库和lib等,如图 ,其中kerneldlls里还有很多动态库,还有一个配置文件.其实这么多的文件,如果我们只用到USBCAN2通信,只需要ker ...
随机推荐
- 201521123064 《Java程序设计》第14周学习总结
本次作业参考文件 数据库PPT MySql操作视频与数据库相关jar文件请参考QQ群文件. 1. 本章学习总结 1.1 以你喜欢的方式(思维导图.OneNote或其他)归纳总结数据库相关内容. 1.数 ...
- 201521123016《Java程序设计》第12周学习总结
1. 本周学习总结 2. 书面作业 将Student对象(属性:int id, String name,int age,double grade)写入文件student.data.从文件读出显示. 1 ...
- 小巧玲珑:机器学习届快刀XGBoost的介绍和使用
欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~ 作者:张萌 序言 XGBoost效率很高,在Kaggle等诸多比赛中使用广泛,并且取得了不少好成绩.为了让公司的算法工程师,可以更加方便的 ...
- [js高手之路]Node.js+jade抓取博客所有文章生成静态html文件
这个周末,恶补了一下jade模板引擎,就为生成静态html文件,这篇文章需要知道jade以及看过我的上篇文章,我先给出他们的参考链接: [js高手之路]Node.js模板引擎教程-jade速学与实战1 ...
- python之面向对象2
一.类命名空间与对象.实例的命名空间 常见一个类就会创建一个类的名称空间,用来储存类中定义的所有名字,这些名字成为类的属性 而类有两种属性:静态属性和动态属性 静态属性就是直接在类中定义的变量 ...
- Socket类 以及 ServerSocket类 讲解
Socket类 套接字是网络连接的端点,套接字使应用可以从网络中读取数据,可以向网络中写入数据.不同计算机上的两个应用程序可以通过连接发送或接收字节流,以此达到相互通信的目的. 为了从一个应用程序向另 ...
- webpack2进阶之多文件,DLL,以及webpack-merge
本需要对webpack已有一定的了解,如果你没接触过webpack或者刚刚接触webpack,可以考虑先看一下我的这篇教程. 入门教程 1.打包多文件 之前,当需要打包多个而文件时,我是这么写的: m ...
- Linux Ubuntu从零开始部署web环境及项目-----搭建ssh环境(一)
linux搭建ssh环境 1,用户登录 成功输入用户名和密码后 进入Ubuntu界面 2,配置网络 参考:http://blog.csdn.net/liu782726344/article/deta ...
- 【编程之外】还记得曾经给'大学导师'写过的报告嘛 --> 前方高能
写在前面 本文不是讲技术的,也没什么代码可看 本文不是讲技术的,也没什么代码可看 本文不是讲技术的,也没什么代码可看 还记得我们曾经给我们大学''导师''写过的报告嘛? 大学他愿意在凌晨6点向你询问近 ...
- 【个人笔记】《知了堂》express模块
NPM 包管理器 Node package module ==>简称npm 类似的bower 安装express 1.全局Npm install express -g 2.项目中安装 项目中 ...