QT 使用 QWebChannel 与 Web 端通信展示文件信息

前言

本文将展示如何使用 QWebChannel 来实现 Web 端与 QT 端之间的交互,同时会通过一个在浏览器端展示文件夹信息的简单例子来展示其具体使用,其功能如下:

  • 获取指定文件夹下的文件信息。
  • 通过使用 QT 的 QFileSystemWatcher 对指定文件夹进行监听,以实现可以获取到文件变更信息并实时展示在浏览器端。

最终实现的效果如下:

动画

本文涉及到的完整代码已上传到GitHub。

阅读本文前需要对 QT 的基础知识(比如信号槽)及 QWebChannel 模块有基本的了解。

实现

QT 端

在创建完项目后,首先需要确保引入了WebChannelWebSockets模块,这里以 MSVC 为例:

image-20240131133251712

image-20240131133110870

完成以上操作后,我们首先需要创建一个WebChannelObj类用于管理所有开放给前端调用方法,头文件内容如下(为方便查看,内容有删减,后续文件都会有些许删减,完整代码可在Github查看):

class WebChannelObj : public QObject
{signals:/// <summary>/// 信息变更事件/// </summary>/// <param name="info">文件信息</param>void infoChanged(const QJsonDocument& info);public slots:/// <summary>/// 获取文件信息/// </summary>/// <returns>转为 JSON 格式的文件信息</returns>QJsonDocument getInfo();};

这里的getInfo方法是直接提供给 Web 端调用的方法,需要定在slots中,infoChanged是提供给 Web 端监听的事件,需要定义在signals中。

对应的 C++ 文件如下:

// 监听的路径
QString dirPath = "D:\\code\\temp\\";WebChannelObj* WebChannelObj::getInstance()
{// 配置监听QFileSystemWatcher* m_FileWatcher = new QFileSystemWatcher;m_FileWatcher->addPath(dirPath);connect(m_FileWatcher, &QFileSystemWatcher::directoryChanged, obj, &WebChannelObj::directoryChanged);return obj;
}QJsonDocument WebChannelObj::getInfo()
{return dirInfo(dirPath);
}void WebChannelObj::directoryChanged(const QString& path)
{// 触发变更事件emit infoChanged(dirInfo(path));
}QJsonDocument WebChannelObj::dirInfo(const QString& path)
{// 根据给定的路径获取目录下的文件信息// 然后封装信息为 JSON 对象并返回QDir dir(path);dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);QFileInfoList list = dir.entryInfoList();QJsonArray jsonArray;for (auto& file : list){QJsonObject obj;obj["isDir"] = file.isDir();obj["fileName"] = file.fileName();obj["fileSize"] = file.size();obj["lastModified"] = file.lastModified().toMSecsSinceEpoch();jsonArray.append(obj);}QJsonDocument doc(jsonArray);return doc;
}

这里使用了QFileSystemWatcher来实现对指定路径进行监听,这样就可以实时获取路径下的最新文件信息,然后通过连接directoryChangedinfoChanged事件,将信息实时返回给前端。

然后我们需要创建一个 WebSocket 服务端用于 QT 与 Web 端通信的桥梁,并在其中将QWebChannelWebSocket进行连接,内容如下:

WebChannelServer::WebChannelServer()
{// 将定义的 WebChannelObj 注册到 QWebChannel 中m_webChannel = new QWebChannel(this);m_webChannel->registerObject("server", WebChannelObj::getInstance());startServer();
}void WebChannelServer::startServer()
{// 启动一个 websocket 服务, 端口为 9999m_websocketServer = new QWebSocketServer("Webchannel", QWebSocketServer::NonSecureMode, this);if (m_websocketServer->listen(QHostAddress::Any, 9999)){connect(m_websocketServer, &QWebSocketServer::newConnection, this, &WebChannelServer::onNewConnection);}
}void WebChannelServer::onNewConnection()
{// 将 QWebChannel 与 WebSocket 进行连接QWebSocket* client = m_websocketServer->nextPendingConnection();m_webChannel->connectTo(new WebSocketTransport(client));
}

其中WebSocketTransport类是我们自定义的用于处理QWebChannelWebSocket和 Web 端通信的类,实现自QWebChannelAbstractTransport这个抽象类,其内容较为固定,就不再介绍其内容,可在GitHub中进行查看。

完成以上操作后,只需要在 main 方法中使用即可:

int main(int argc, char *argv[])
{QGuiApplication app(argc, argv);//...省略内容// 使用WebChannelServer webChannelServer;return app.exec();
}

到此为止, QT 端的工作就算完成了。

Web 端

相比于 QT 端,Web 端的使用就很简单了,首先我们需要先引用一个qwebchannel.js文件,这个文件由官方提供,可以在 QT 安装目录的 Examples 中找到:

image-20240131141033266

然后就可以直接使用了:

<script>
import { QWebChannel } from '@/assets/qwebchannel'export default {name: 'App',data() {return {// 文件列表fileList: []}},mounted() {const websocket = new WebSocket('ws://localhost:9999')websocket.onopen = () => {new QWebChannel(websocket, channel => {// server 就是前文中通过 m_webChannel->//   registerObject("server", WebChannelObj::getInstance()); 注册的名字  const webChannelObj = channel.objects.server// infoChanged 是我们在 signals 中定义的提供给前端的监听事件// 只要有文件变更事件, 这里通过 connect 就可以获取到相应的回调事件webChannelObj.infoChanged.connect(data => {this.fileList = data})// getInfo 是我们在 slots 中定义的提供给前端的方法// 返回值需要通过回调获取  webChannelObj.getInfo(data => {this.fileList = data})})}}
}
</script>

关于上述代码的含义参考相应的注释即可,这里只需要知道如果我们想给前端提供监听事件,只需要参考 infoChanged 的定义,在前端通过 xxx.connect(data => {})就可以在回调中获取相关信息。如果想给前端提供可以直接调用的方法,只需要参考 getInfo 的定义,通过需要注意返回值也需要通过回调函数进行获取,如果方法包含参数,则按照正常传参(如果传递了对应,QT 中可以使用 QJsonObject 进行接收),同时把回调函数始终作为最后一个参数即可。

总结

本文通过一个简单的例子展示了如何使用 QWebChannel 及 WebSocket 来实现 QT 与 Web 端的通信,通过使用 QWebChannel ,我们可以很方便地在 Web 端调用 QT 中的定义方法以及实现两端的通信(例如在 Web 端通过 QT 获取摄像头然后展示在 Web 端)。本文如果有错误或不当之处,也欢迎一起交流讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/658281.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言 | 求最大/小值小技巧:fmax、fmin函数

如果你只是因为不想用C语言手写max、min函数&#xff0c;就直接去用iostream中的max、min函数的话&#xff0c;这篇文章可能会有些许帮助。 &#x1f607; fmax、fmin函数用于确定两个指定值的较大/较小值。 头文件 math.h&#xff08;或者cmath&#xff09;。 定义 double …

2023年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷9

某企业根据自身业务需求&#xff0c;实施数字化转型&#xff0c;规划和建设数字化平台&#xff0c;平台聚焦“DevOps开发运维一体化”和“数据驱动产品开发”&#xff0c;拟采用开源OpenStack搭建企业内部私有云平台&#xff0c;开源Kubernetes搭建云原生服务平台&#xff0c;选…

Android systemui 编译

目录 简介&#xff1a; 一、步骤 二、下载源码 三、环境配置 四、确定好需要编译版本 五、编译SystemUI 步骤1&#xff1a;进入源代码目录 步骤2&#xff1a;初始化编译环境 步骤3&#xff1a;选择目标设备 步骤4&#xff1a;编译SystemUI 步骤5&#xff1a;查找生成…

网络安全全栈培训笔记(59-服务攻防-中间件安全CVE复现lSApacheTomcataNginx)

第59天 服务攻防-中间件安全&CVE复现&lS&Apache&Tomcata&Nginx 知识点&#xff1a; 中间件及框架列表&#xff1a; lIS,Apache,Nginx,Tomcat,Docker,Weblogic,JBoos,WebSphere,Jenkins, GlassFish,Jira,Struts2,Laravel,Solr,Shiro,Thinkphp,Sprng,Flask,…

Ubuntu系统安装 Redis

环境准备 Ubuntu 系统版本&#xff1a;22.04.3Redis 版本&#xff1a;6.2.12 检查本地 make 环境 make -version若没有安装&#xff0c;则需要安装 sudo apt install make检查本地 gcc 环境 gcc -version若没有安装&#xff0c;则需要安装 sudo apt install gcc。 sudo a…

服装行业ERP系统解决方案

我国的服装企业大多属于劳动密集型&#xff0c;主要有三种类型&#xff1a;自有品牌服装生产销售企业、接订单生产型企业及处于产业链下游的零售分销企业。在经营过程中&#xff0c;服装行业面临诸多挑战&#xff0c;如流行周期短、季节性强&#xff0c;市场变化快&#xff1b;…

Vue学习Element-ui

声明&#xff1a;本文来源于黑马程序员PDF讲义 Ajax 我们前端页面中的数据&#xff0c;如下图所示的表格中的学生信息&#xff0c;应该来自于后台&#xff0c;那么我们的后台和前端是 互不影响的2个程序&#xff0c;那么我们前端应该如何从后台获取数据呢&#xff1f;因为是2…

博云科技与中科可控全面合作,探索前沿金融科技新机遇

2024年1月26日&#xff0c;博云科技与中科可控在昆山高新区成功举办合作签约仪式。昆山市委常委、昆山高新区党工委书记孙道寻、中科可控董事长聂华、博云科技董事长花磊等领导出席了本次签约仪式。 中科可控将利用其在先进计算和智造领域的优势&#xff0c;为博云科技提供有关…

AI人工智能可以怎么应用?——GPT4v图文识别问答功能

沃卡 AI 已支持 AI识图问答TTS语音对话文档总结对话Dall E3 对话文生图国内大模型集合AI 绘画思维导图&#xff0c;而且功能还在不断更新优化&#xff0c;丰富好用&#xff01;一个系统满足您多个需求&#xff01; 大家可以通过收藏网页www.woka.chat 直接进行访问&#xff0c…

springboot-前后端分离——第一篇

本篇主要对前后端分离的一些基础知识进行总结&#xff0c;主要对HTTP请求协议、HTTP响应格式、Http协议解析等进行总结。重点在于简单了解前端如何向服务端发送请求&#xff0c;服务端如何接收请求并返回响应结果。 一、简单案例&#xff1a; 首先创建一个springboot项目&…

异步任务的一些思考

前言 XXL-Job部署教程 项目中&#xff0c;必然少不了数据的导入导出&#xff0c;针对数据的导入导出简单复盘一下。 为了不占用资源消耗时间&#xff0c;影响用户体验&#xff0c;大量数据的导入导出一般都是异步执行 导入的时候&#xff0c;如果数据量很大&#xff0c;一次…

Wireshark网络协议分析 - TCP协议

在我的博客阅读本文 文章目录 1. 基础2. 实战2.1. 用Go写一个简单的TCP服务器与客户端2.2. Wireshark抓包分析2.3. 限制数据包的大小——MSS与MTU2.4. 保证TCP的有序传输——Seq&#xff0c;Len与Ack2.5. TCP头标志位——URG&#xff0c;ACK&#xff0c;PSH&#xff0c;RST&…

cleanmymacX有必要买吗

CleanMyMac X是一款被广泛推荐的Mac电脑清理软件。以下是关于是否购买CleanMyMac X的几个关键点&#xff1a; 软件功能&#xff1a;CleanMyMac X具备多项功能&#xff0c;包括但不限于系统垃圾清理、缓存清理、恶意软件移除、隐私保护等。这些功能有助于保持Mac电脑的清洁和性能…

StarRocks -- 基础概念(数据模型及分区分桶)

1. 数据模型 StarRocks提供四种数据模型&#xff1a; Duplicate Key, Aggregate Key, Unique Key, Primary Key 1.1 Duplicate Key 适用场景&#xff1a; 分析原始数据&#xff0c;如原始日志和原始操作记录。可以使用多种方法查询数据&#xff0c;不受预聚合方法的限制。加…

第七篇:node中间件详解

&#x1f3ac; 江城开朗的豌豆&#xff1a;个人主页 &#x1f525; 个人专栏 :《 VUE 》 《 javaScript 》 &#x1f4dd; 个人网站 :《 江城开朗的豌豆&#x1fadb; 》 ⛺️ 生活的理想&#xff0c;就是为了理想的生活 ! ​ 目录 &#x1f4d8; 引言&#xff1a; &#…

【Opcua】 客户端读写时,Opcua Server信息返回处追溯(1)

【Opcua】 客户端读写时&#xff0c;Opcua Server信息返回处追溯&#xff08;1&#xff09; 前言从客户端角度展开分析从服务端角度展开分析 前言 基于前文【Node-RED】node-red-contrib-opcua-server模块使用&#xff08;2&#xff09;介绍&#xff0c;我们已经了解到NodeRed…

【EI会议征稿通知】第四届信号图像处理与通信国际学术会议(ICSIPC 2024)

第四届信号图像处理与通信国际学术会议&#xff08;ICSIPC 2024&#xff09; 2024 4th International Conference on Signal Image Processing and Communication 第四届信号图像处理与通信国际学术会议&#xff08;ICSIPC2024&#xff09;将于2024年5月17日-19日在陕西西安再…

用友NC Cloud及YonBIP PMCloudDriveProjectStateServlet JNDI注入漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

【伪类·HTML】

伪类 在 CSS 中&#xff0c;伪类是添加到选择器的关键字&#xff0c;给指定元素设置一些特殊状态&#xff0c;以 : 开头。 链接有以下四个状态。这四种状态也称之为超链接的伪类。 对于超链接的伪类&#xff0c;推荐的使用顺序是&#xff1a; :link - :visited - :hover - :a…

代码随想录刷题笔记-Day15

1. 完全二叉树的的节点个数 222. 完全二叉树的节点个数https://leetcode.cn/problems/count-complete-tree-nodes/ 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能没…