Qt QWebChannel web端js与C++交互
文章目录
- 1. QWebChannel
- 2. 使用QWebEngine的示例
- 2.1 C++端代码
- 2.1.1 mainwindow.cpp
- 2.1.2 mytestclass.h
- 2.1.3 mytestclass.cpp
- 2.2 Web端
- 2.3 运行
- 3. 使用WebSocket的示例
- 3.1 C++端代码
- 3.1.1 mainwindow.cpp
- 3.2 Web端代码
- 3.3 运行
- 3.4 问题
- 4. 代码
1. QWebChannel
QWebChannel类的作用是向远端HTML客户端暴露 QObject。
QWebChannel填补了C++应用程序和HTML/JavaScript 应用程序之间的空白。通过将QObject派生对象发布到QWebChannel并在HTML中引入qwebchannel.js脚本可从此处获取。在HTML端,可以透明地访问QObject的属性、公共槽和方法。不需要手动消息传递和数据序列化,C++方面的属性更新和信号发射将自动传输到可能远程运行的HTML客户机。在客户端,将为任何发布的C++ QObject创建JavaScript对象。它反映了C++对象的API,因此可以直观地使用。
但是,Web端与C++之间怎么进行通信能? 有两个方法:
QWebEngine
提供一个 web 引擎,用于在 Qt 应用中嵌入任意的网页内容。Qt WebEngine 是基于 Chromium 项目实现的,提供了一个 js 的宿主环境,内部实现了js调用C++的环境;Websocket
C++端建立websocket server,Web端连接,qwebchannel.js会获取到C++端所有的属性、槽函数等。
2. 使用QWebEngine的示例
2.1 C++端代码
2.1.1 mainwindow.cpp
// 要导出的类,此类供js调用
m_myTestClass = new MyTestClass(this);// 创建QWebChannel,把创建的类注册到QWebChannel中,js才能调用此类的方法
m_webChannel = new QWebChannel(this);
m_webChannel->registerObject("mytestclass", m_myTestClass);// js与C++通信方式一、使用QWebEngineView加载网页,web端js与C++之间的通信
QString strHtml = QApplication::applicationDirPath() + "/../../testWeb/test.html";
// QWebEngineView 基于 Chromium 的 web 引擎
m_webEngineView = new QWebEngineView(this);
m_webEngineView->load(QUrl::fromLocalFile(strHtml));
m_webEngineView->page()->setWebChannel(m_webChannel);
ui->verticalLayout->addWidget(m_webEngineView);
导出类 MyTestClass
,供js调用
2.1.2 mytestclass.h
#ifndef MYTESTCLASS_H
#define MYTESTCLASS_H#include <QObject>
#include <QThread>class MyTestClass : public QObject
{Q_OBJECT// 导出的属性Q_PROPERTY(QString navStatus MEMBER m_navStatus NOTIFY navStatusChanged)public:explicit MyTestClass(QObject *parent = nullptr);signals:// 导出的事件void navStatusChanged(const QString& navStatus);public slots:// 导出的槽函数void function1(const QString& str);private:void setNavStatus(const QString& status);QString m_navStatus;};#endif // MYTESTCLASS_H
2.1.3 mytestclass.cpp
#include "mytestclass.h"#include <QMessageBox>
#include <QVariant>
#include <QDebug>MyTestClass::MyTestClass(QObject *parent) : QObject(parent),m_navStatus("hello")
{}void MyTestClass::function1(const QString& str)
{setNavStatus(str);qDebug() << __FUNCTION__ << str;
}void MyTestClass::setNavStatus(const QString &status)
{m_navStatus = status;emit navStatusChanged(m_navStatus);
}
2.2 Web端
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><button id="callcpp" onclick="callcpp()">callcpp</button><button onclick="getValue()">getValue</button><script src="qwebchannel.js"></script><script type="text/javascript">var webObj;// 创建Webchannel,与C++端建立连接new QWebChannel(qt.webChannelTransport, function (channel) {// 获取类的对象webObj = channel.objects.mytestclass;// 类的事件webObj.navStatusChanged.connect(function(arg){alert("navStatusChanged: " + arg);});});function callcpp(){// 类的方法webObj.function1('this is a test');}function getValue(){// 类的属性值var status = webObj.navStatus;alert(status);}</script>
</body>
</html>
其中,qwebchannel.js
取自 Qt安装目录的 Qt5.12.0\Examples\Qt-5.12.0\webchannel\shared
目录。
2.3 运行
QT UI加载了html页面,显示了其中的元素。
(1)Web端的getValue
获取C++对象的属性navStatus
,属性初始值为 “hello”
(2)Web端的 callcpp
调用 C++端的函数 function1
,C++端function1函数中打出
(3)Web端响应 navStatusChanged
事件
3. 使用WebSocket的示例
3.1 C++端代码
3.1.1 mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);// 要导出的类,此类供js调用m_myTestClass = new MyTestClass(this);// 创建QWebChannel,把创建的类注册到QWebChannel中,js才能调用此类的方法m_webChannel = new QWebChannel(this);m_webChannel->registerObject("mytestclass", m_myTestClass);// js与C++通信方式二、创建QWebsocketServer,web端与之建立连接startServer();}MainWindow::~MainWindow()
{delete ui;
}// 建立WebSocket服务
void MainWindow::startServer()
{m_websocketServer = new QWebSocketServer("testWebchannel", QWebSocketServer::NonSecureMode, this);if(!m_websocketServer->listen(QHostAddress::Any, 12345)){qDebug() << "websocket server listen failed, error: " << m_websocketServer->errorString();return;}connect(m_websocketServer, &QWebSocketServer::newConnection, this, &MainWindow::onNewConnection);qDebug() << "startServer";
}void MainWindow::onNewConnection()
{QWebSocket* client = m_websocketServer->nextPendingConnection();qDebug() << (QString("Homay robot server has new connection from %1.%2").arg(client->peerAddress().toString()).arg(client->localPort()));auto pTransport = new WebSocketTransport(client);// 可以不需要,这里只是为了调试打印js端的qwebchannel.js是怎么和C++端通信的,通信协议是什么样的connect(pTransport, &WebSocketTransport::messageReceived, this, &MainWindow::onTransportMessageReceived);m_webChannel->connectTo(pTransport);
}void MainWindow::onTransportMessageReceived(const QJsonObject &message, QWebChannelAbstractTransport *transport)
{qDebug() << "onTransportMessageReceived: " << message;
}
导出类 MyTestClass
,供js调用。
代码中 WebSocketTransport
类代码,取自 Qt安装目录的 Qt5.12.0\Examples\Qt-5.12.0\webchannel\shared
目录下的 websockettransport.h
websockettransport.cpp
。
此处省略。
3.2 Web端代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><button id="callcpp" onclick="callcpp()">callcpp</button><button onclick="getValue()">getValue</button><script src="qwebchannel.js"></script><script type="text/javascript">var webObj;// 连接c++端的 Websocketvar socket = new WebSocket('ws://127.0.0.1:12345');// 连接成功后socket.onopen = function(){alert("onopen");// 创建Webchannelnew QWebChannel(socket, function (channel) {// 获取类的对象webObj = channel.objects.mytestclass;// 类的事件webObj.navStatusChanged.connect(function(arg){alert("navStatusChanged: " + arg);});});}function callcpp(){// 类的方法webObj.function1('this is a test');}function getValue(){// 类的属性值var status = webObj.navStatus;alert(status);}</script>
</body>
</html>
与2.2中的Web端代码相比,此时,需要先创建WebSocket连接,把socket传入QWebChannel中。
3.3 运行
(1)运行C++, C++代码没有加载html, 此时为空界面;
(2)使用Chrome浏览器,或者Edge浏览器打开Web测试网页,一打开就与C++端的websocket连接上了
(3)接下来与2.3的演示一样。
3.4 问题
我这里端口用的12345,可能在有些电脑上此端口被占用了,会报错:
改一下端口号就好了, 比如我改成:
4. 代码
所有代码详见:QWebChannel
Qt QWebChannel web端js与C++交互相关推荐
- Emqx3.4.4(企业版试用) web端 js实现消息的发布接收
本文只介绍如何进行消息的发布,接收,至于emqx服务器需要靠 小伙伴们自己 本文章emq服务器为企业版试用,但消息的接收发布与emqx broker是一样的 Paho.mqtt.js Paho 是 E ...
- Web 端 js 导出csv文件(使用a标签)
前言 导出文件,使用最多的方式还是服务器端来处理.比如jsp 中使用response 的方式. 但是,有时候可能就想使用web 前端是否也可以把页面上的内容导出来呢? 比如说,导出页面的一个表格. 这 ...
- 高德地图 web 端 JS API 遇到的坑及性能优化
[JS API V2.0] 本指望全面提升一下性能,结果发现一些硬伤,迫不得已转到1.4.15版本,先说一下最新的v2.0的问题. 因为务业需要规划线路,但是这个版本中,规划线路,并且经过中间点时,部 ...
- vue使用高德地图web端JS API(vue-amap插件)
高德地图地图 JS API v2.0:https://lbs.amap.com/api/jsapi-v2/summary/ vue-amap(基于Vue 2.0和高德地图的地图组件):https:// ...
- web 端JS取得window 的按键动作(按下Shift, Alt,Ctrl....)
如何取得 基本上都是从动作的event 中去判断. IE下的处理 在IE中, window 对象里就有包含event. 看例子: <!--Add by oscar999--> <!D ...
- 高德地图web端js
下面是一些高德地图使用例子,自定义展示,右击拖动,搜索,画圆,定位等功能,没有整理仅供参考 var infoWindow = new AMap.InfoWindow({isCustom:true,// ...
- 论文研读-图可视化-NetV.js:Web端可视化工具库
NetV.js:一个基于网络的用于大规模图和网络的高效可视化的库 1 论文概述 1.1 文章摘要 1.2 引言 1.3 文章脉络 2 相关工作 3 设计 3.1 设计要求 3.2 设计细节 3.2.1 ...
- WEB端Monkey测试gremlins.js
一直想做web端UI自动化测试,网上查阅了 大量的资料,发现有一个线程的monkey测试工具,地址:https://github.com/marmelab/gremlins.js.但是我对js不是很精 ...
- web电商系统、电商平台WEB端交互原型模板、用户中心、会员中心、优惠券、积分、互动社区、运营推广、内容推荐、商品展示、订单流程、订单管理、售后及服务、Axure原型、rp原型、电商原型、商城系统原型
作品介绍:web电商系统.电商平台WEB端交互原型模板.用户中心.会员中心.优惠券.积分.互动社区.运营推广.内容推荐.商品展示.订单流程.订单管理.售后及服务等完整的电商体系功能架构和业务流程 Ax ...
最新文章
- Ajax跨域请求action方法,无法传递及接收cookie信息(应用于系统登录认证及退出)解决方案
- python断点续传下载_Python版本,图片,视频断点续传下载
- qt 判断ctrl键被按下_惊雷!证监会公告,又一家千亿白马股被按下“暂停键”...
- 九十九、Python所学经验分享
- C#设计模式(5)-Factory Method Pattern
- php提交表单显示错误,php – 在提交注册表单时使用jQuery显示错误
- 每个人都应该使用的Python 3中被忽略的3个功能
- 前端学习(1081):构造函数和原型概述
- 2019牛客暑期多校训练营(第三场) B-Crazy Binary String
- 屏幕的宽度_交互规范:响应式让屏幕利用更高,用户体验更佳
- 40个非常有创意的国外LOGO欣赏(上)
- Imagej分析所有气泡的粒径
- 【优化求解】基于matlab改进的遗传算法求解带约束的优化问题【含Matlab源码 1773期】
- SoftCnKiller高速下载器捆绑软件杀手
- Selpg—Golang
- ubuntu系统启动项的修改
- CSS实现优惠券特殊样式的技巧
- [深度学习] (sklearn)多层感知机对葡萄酒的分类
- 你要找到黑夜里代替阳光的东西,那个叫做信念
- [原创].NET中防止Access数据库下载
热门文章
- python视频搬运_Python-自动下载抖音无水印高清视频
- 【PTA】 7-3 玩转二叉树 (二叉树静态建树+左右子树交换+层次遍历)
- 有了中值联区块链证书我们对钓鱼网站说“不”
- 计算机会计中出纳的职责有哪些,作为一名学校出纳工作职责有哪些
- modbus/施耐德PLC协议网关
- 【Android】Android设备唯一标识简介
- Specify @BootstrapWith's 'value' attribute or make the default bootstrapper class available.
- 商业世界的交易结构到底有哪些?
- 深度学习论文精读[10]:Deeplab v1
- 达梦数据库基础知识(十一)管理分区表和分区索引