当前位置: 首页 > article >正文

qt与html通信

**Cef视图(CefView)**是指在使用Chromium Embedded Framework(CEF)时,嵌入到应用程序中的浏览器视图。CEF是一个开源项目,它基于Google的Chromium浏览器,允许开发者将Web浏览器功能嵌入到自己的应用程序中。
html文件

<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><title>Login</title><link rel="stylesheet" type="text/css" href="Login.css"/>
</head>
<body onload="onLoad()" id="main" class="noselect"><div id="login"><!-- 消息发送区 --><form method="post"><input id="account" type="text" required placeholder="请输入" name="u"><button id="sendBtn" class="but" type="button" onclick="onCallBridgeQueryClicked('html')">发送</button><textarea id="output" required placeholder="内容" name="t"></textarea></form><!-- 测试按钮区 --><button class="but" type="button" onclick="onInvokeMethodClicked('message1', '标题', '这是message1', 'a', 1.1)">Message1</button><button class="but" type="button" onclick="onInvokeMethodClicked('message2', '标题', '这是message2', 'B', 2.2)">Message2</button></div><script>// ==================== 事件处理函数 ==================== ///*** 处理Qt发送的apChange事件* @param {string} flag 事件标识* @param {...any} arg 可变参数列表*///该函数响应"apChange"信号,负责将接收到的消息显示在页面的文本区域(output)中function ap(flag, ...arg) {const mess = arg[0]; // 获取第一个参数if (mess) {const output = document.getElementById('output');  //获取页面上的输出文本框//格式化消息:"[flag]: [mess]"const newText = `${flag}: ${mess}`;//将接收到的消息显示在页面的文本区域(output)中output.value = output.value  ? `${output.value}\n${newText}`   // 非空时换行追加: newText;                    // 空时直接显示}}/*** 处理Qt发送的sendFailChange事件(错误消息)*/function sendFail(flag, ...arg) {const output = document.getElementById('output');const newText = `${flag}: ${arg[0]}`;output.value = output.value ? `${output.value}\n${newText}` : newText;}// ==================== 初始化函数 ==================== ///*** 页面加载完成后初始化CEF通信*/function onLoad() {if (typeof CallBridge === "undefined") {alert("Not in CefView context");return;}// 注册Qt事件监听CallBridge.addEventListener("apChange", ap); //apchange信号绑定ap函数CallBridge.addEventListener("sendFailChange", sendFail);}// ==================== JS → Qt通信 ==================== ///*** 调用Qt方法(无返回值)* @param {string} name 方法名* @param {...any} arg 可变参数*/function onInvokeMethodClicked(name, ...arg) {window.CallBridge.invokeMethod(name, ...arg);}/*** 发送查询请求到Qt(需要返回值)*/function onCallBridgeQueryClicked(name) {const message = document.getElementById("account").value.trim();if (!message) return;// 清空输入框document.getElementById("account").value = '';// 更新本地消息显示const output = document.getElementById('output');const newText = `${name}: ${message}`;output.value = output.value ? `${output.value}\n${newText}` : newText;// 构建并发送请求window.CefViewQuery({request: `${name}|${message}`,onSuccess: (response) => console.log("成功:", response),onFailure: (code, msg) => {output.value += `\n错误(${code}): ${msg}`;}});}</script>
</body>
</html>

css文件

html{   width: 100%;   height: 100%;   overflow: hidden;   font-style: sans-serif;   
}   
body{   width: 100%;   height: 100%;   font-family: 'Open Sans',sans-serif;   margin: 0;   background-color: #0f8fdf;   
}   
#login{   position: absolute;   top: 50%;   left:50%;   margin: -150px 0 0 -150px;   width: 300px;   height: 300px;   
}   
#login h1{   color: #fff;   text-shadow:0 0 10px;   letter-spacing: 1px;   text-align: center;   
}   
h1{   font-size: 2em;   margin: 0.67em 0;   
}   
input{   width: 278px;   height: 18px;   margin-bottom: 10px;   outline: none;   padding: 10px;   font-size: 13px;   color: #fff;   //text-shadow:1px 1px 1px;   border-top: 1px solid #312E3D;   border-left: 1px solid #312E3D;   border-right: 1px solid #312E3D;   border-bottom: 1px solid #56536A;   border-radius: 4px;   background-color: #2D2D3F;   
}   
.but{   width: 300px;   min-height: 20px;   display: block;   background-color: #9cc7e3;   border: 1px solid #9cc7e3;   color: #fff;   padding: 9px 14px;   font-size: 15px;   line-height: normal;   border-radius: 5px;   margin: 0;   
}  textarea{   width: 300px;   height: 200px;   margin-bottom: 10px;   outline: none; resize: none;			pointer-events: none;	font-size: 13px;       border-top: 1px solid #312E3D;   border-left: 1px solid #312E3D;   border-right: 1px solid #312E3D;   border-bottom: 1px solid #56536A;   border-radius: 4px;     
}  

Qt应用程序中嵌入Cef浏览器

获取html文件路径:

   //获取html文件路径QDir dir = QCoreApplication::applicationDirPath();QString path = QDir::toNativeSeparators(dir.filePath("html"));  

将本地html文件夹映射为一个URL,在cef浏览器里加载我们的html文件

  QCefContext::instance()->addLocalFolderResource(path, "my://cpp_learners");  

new一个cef浏览器对象,加载指定html文件

 cefViewWidget = new QCefView("my://cpp_learners/QCefViewTest.html", &setting, this);

把cef浏览器嵌入QT界面

    QGridLayout* layout = new QGridLayout(this);layout->addWidget(cefViewWidget, 0, 0, 1, 1);ui.widgetHtml->setLayout(layout);

Qt → HTML 通信详解

Qt主动向html发送数据:

            QVariantList data;QString str=ui.lineEditInput->text();          data << "qt" << "str";QCefEvent event("apChange"); //创建事件,名称为"apChange"event.setArguments(list);   //绑定发给前端的数据cefViewWidget->broadcastEvent(event); //发送事件到前端ui.lineEditInput->clear();  //清空输入框

HTML接收

// 注册事件监听function onLoad() //页面加载完成后初始化CEF通信{CallBridge.addEventListener("apChange", ap); //apchange信号绑定ap函数}//该函数响应"apChange"信号,负责将接收到的消息显示在页面的文本区域(output)中function ap(flag, ...arg) {const mess = arg[0]; // 获取第一个参数if (mess) {const output = document.getElementById('output');  //获取页面上的输出文本框//格式化消息:"[flag]: [mess]"const newText = `${flag}: ${mess}`;//将接收到的消息显示在页面的文本区域(output)中output.value = output.value  ? `${output.value}\n${newText}`   // 非空时换行追加: newText;                    // 空时直接显示}}

HTML → Qt 通信详解

HTML端发送

单击发送按钮会触发onCallBridgeQueryClicked槽函数:

<button id="loginBtn" class="but" type="button" onclick="onCallBridgeQueryClicked('html')">发送</button>

onCallBridgeQueryClicked函数内部操作

(1) 获取用户输入
var message = document.getElementById("account").value;
(2) 构建请求字符串
var str = "html" + "|" + message;  // 例如:"html|你好Qt"
(3) 发送到Qt(通过CEF的 CefViewQuery API发送数据)
window.CefViewQuery({request: str,          // 要发送的数据onSuccess: on_success, // 成功回调(当前未实现具体逻辑)onFailure: on_failure  // 失败回调(会显示错误信息)
});

QT端接收

  • HTML/JavaScript 调用 window.CefViewQuery() 时,CEF 会触发 cefQueryRequest 信号。
  • Qt 通过连接这个信号到 onQCefQueryRequest 槽函数,接收并处理来自网页的请求。
    // 绑定信号CefViewQueryconnect(cefViewWidget, &QCefView::cefQueryRequest, this, &QCefView_Test::onQCefQueryRequest);

onQCefQueryRequest函数(接收html发来的数据)

void QCefView_Test::onQCefQueryRequest(int browserId, int frameId, const QCefQuery& query) {// 分割字符串auto parts = query.request().split("|");QString messageType = parts[0];  // "html"QString content = parts[1];      // 用户输入的内容// 处理消息...query.setResponseResult(true, "处理成功"); // 可选:返回响应cefViewWidget->responseQCefQuery(query);  // //给js返回结果
}

更新ui

// 在output文本区域显示发送的内容
document.getElementById('output').value += "\nhtml: " + message;

js->Qt发送弹窗

单击Message按钮调用onInvokeMethodClicked槽函数

<button class="but" type="button" onclick="onInvokeMethodClicked('message1', '标题', '这是message1', 'a', 1.1)">

onInvokeMethodClicked()函数进行js调用

   function onInvokeMethodClicked(name, ...arg) {window.CallBridge.invokeMethod(name, ...arg);}

具体调用内容:

window.CallBridge.invokeMethod("message1", "标题",      // → str1"这是消息1", // → str2"这是消息2", // → str31.1         // → f1
);
  • HTML/JavaScript 调用 window.CallBridge.invokeMethod() 时,CEF 会触发 invokeMethod 信号。
  • Qt 通过连接这个信号到 onInvokeMethod 槽函数,执行对应的逻辑。

connect

    // 绑定信号invokeMethodconnect(cefViewWidget, &QCefView::invokeMethod, this, &QCefView_Test::onInvokeMethod);

onInvokeMethod()函数

void QCefView_Test::onInvokeMethod(int browserId, int frameId, const QString& method, const QVariantList& arguments)
{
if (0 == method.compare("message1")) {// 从参数列表提取数据QString str1 = arguments[0].toString();  // 第1个参数 → 标题QString str2 = arguments[1].toString();  // 第2个参数 → 消息1QString str3 = arguments[2].toString();  // 第3个参数 → 消息2float f1 = arguments[3].toFloat();       // 第4个参数 → 浮点数int in1 = arguments.size();              // 参数总数// 在Qt界面显示日志ui.textEditText->append("您有消息弹窗提醒1"); // 格式化消息并弹窗QString str = QString("%1,%2,%3,%4").arg(str2).arg(str3).arg(f1).arg(in1);QMessageBox::information(this, str1, str); // 弹窗显示
}
}

代码仓库:
https://gitee.com/sun-Penghu/qt/tree/master/QCefView1

相关文章:

qt与html通信

**Cef视图&#xff08;CefView&#xff09;**是指在使用Chromium Embedded Framework&#xff08;CEF&#xff09;时&#xff0c;嵌入到应用程序中的浏览器视图。CEF是一个开源项目&#xff0c;它基于Google的Chromium浏览器&#xff0c;允许开发者将Web浏览器功能嵌入到自己的…...

git 根据http url设置账号密码

1. 原因 场景&#xff1a;有一种情况&#xff0c;比如在github上面有多个账号&#xff0c;并且每个账号都有些仓库的内容需要修改&#xff0c;并且这些账号自己&#xff0c;不是协作者的关系。这个时候需要针对每个仓库的url设置用户名密码, 2. 设置 2.1 第一步&#xff1a;…...

【CVE-2024-10929】ARM CPU漏洞安全通告

安全之安全(security)博客目录导读 目录 一、概述 二、CVE详情 三、受影响产品 四、建议措施 五、致谢 六、版本历史 一、概述 在部分基于Arm架构的CPU中发现了一个潜在安全问题&#xff0c;称为Spectre-BSE&#xff08;Branch Status Eviction&#xff0c;分支状态驱逐…...

OpenCV 图形API(33)图像滤波-----高斯模糊函数gaussianBlur()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 使用高斯滤波器对图像进行模糊处理。 该函数使用指定的高斯核对源图像进行滤波。输出图像必须与输入图像具有相同的类型和通道数。 cv::gapi::g…...

【Android】 如何将 APK 内置为系统应用(适用于编辑设置属性)

如何将 APK 内置为系统应用(适用于编辑设置属性) 在 Android 中&#xff0c;将 APK 文件内置为系统应用涉及到一系列的命令和步骤。以下是详细的操作流程&#xff0c;帮助您解决常见问题&#xff0c;如 /system not in /proc/mounts 的错误。 挂载system/app获取可读写权限 …...

【2025最新版】火鸟门户v8.5系统源码+PC、H5、小程序 +数据化大屏插件

一.介绍 火鸟地方门户系统V8.5源码 系统包含4端&#xff1a; PCH5小程序APP 二.搭建环境 系统环境&#xff1a;CentOS、 运行环境&#xff1a;宝塔 Linux 网站环境&#xff1a;Nginx 1.2.22 MySQL 5.6 PHP-7.4 常见插件&#xff1a;fileinfo &#xff1b; redis 三.测…...

关于 传感器 的详细解析,涵盖定义、分类、工作原理、常见类型、应用领域、技术挑战及未来趋势,结合实例帮助理解其核心概念

以下是关于 传感器 的详细解析&#xff0c;涵盖定义、分类、工作原理、常见类型、应用领域、技术挑战及未来趋势&#xff0c;结合实例帮助理解其核心概念&#xff1a; 一、传感器的定义与核心功能 1. 定义 传感器&#xff08;Sensor&#xff09;是一种能够将物理量&#xff…...

EtherCAT转ProfiNet边缘计算网关配置优化:汽车制造场景下PLC与机器人协同作业案例

1.行业背景与需求分析 智能汽车焊装车间是汽车制造的核心工艺环节&#xff0c;某德国豪华品牌在其上海MEB工厂新建的焊装车间中&#xff0c;采用西门子S7-1500PLC作为ProfiNet主站&#xff0c;负责整线协调与质量追溯&#xff1b;同时部署KUKAKR1500Titan机器人&#xff08;Eth…...

极狐GitLab CI/CD 流水线计算分钟数如何管理?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 计算分钟管理 (PREMIUM SELF) 在极狐GitLab 16.1 中&#xff0c;从 CI/CD 分钟数重命名为计算配额或计算分钟数。 管理员可…...

HTTP协议 --- 超文本传输协议 和 TCP --- 传输控制协议

是基于 TCP 协议的 80 端口的一种 C/S 架构协议。 特点&#xff1a;无状态 --- 数据传输完成后&#xff0c;会断开 TCP 连接&#xff0c;哪怕浏览器还正常运行。 请求报文 --- 方法 响应报文 --- 状态码 是一种面向连接的可靠传输协议 。 面向连接 --- 在传输数据之前&am…...

类和对象(下篇)(详解)

【本节目标】 1. 再谈构造函数 2. Static成员 3. 友元 4. 内部类 5. 再次理解封装 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数&#xff0c;给对象中各个成员变量一个合适的初始值。 #include <iostream> using name…...

Uniapp:获取当前定位坐标

目录 一、出现场景二、具体使用 一、出现场景 在项目的开发中&#xff0c;会出现打卡、定位当前位置的功能&#xff0c;那我们如何获取当前位置呢&#xff1f;这就需要使用getLocation来获取当前位置坐标 二、具体使用 uni.getLocation({type: wgs84, // 返回可以用于uni.op…...

最大子序和问题——动态规划/贪心算法解决

目录 一&#xff1a;问题描述 二&#xff1a;解决思路1——动态规划思想 三&#xff1a;C 语言代码实现 四&#xff1a;复杂度分析 五&#xff1a;解决思路2——贪心算法思想 六&#xff1a;具体步骤 七: C语言代码实现 八&#xff1a;复杂度分析 一&#xff1a;问题描述 …...

【Unity】JSON数据的存取

这段代码的结构是为了实现 数据的封装和管理&#xff0c;特别是在 Unity 中保存和加载玩家数据时。以下是对代码设计的逐步解释&#xff1a; 1. PlayerCoin 类 PlayerCoin 是一个简单的数据类&#xff0c;用于表示单个玩家的硬币信息。它包含以下字段&#xff1a; count&…...

LeetCode【剑指offer】系列(位运算篇)

剑指offer15.二进制中1的个数 题目链接 题目&#xff1a;编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 ‘1’ 的个数&#xff08;也被称为 汉明重量).&#xff09;。 思路一&#xff…...

unity socket 客户端和c#服务器通信

服务器 using BarrageGrab; using System; using System.Collections.Concurrent; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading;namespace Lyx {class Server{private TcpListener listener;private Concurre…...

如何在Vue中实现取消聚焦el-select——从零到部署的完整指南

如何在Vue中实现取消聚焦el-select——从零到部署的完整指南 在开发Vue项目时&#xff0c;经常会遇到需要处理用户交互和组件状态管理的情况。特别是在使用Element UI组件库时&#xff0c;如何优雅地管理组件的状态显得尤为重要。本文将详细介绍如何在取消对话框时自动取消el-s…...

网络安全领域的AI战略准备:从概念到实践

网络安全领域的AI准备不仅涉及最新工具和技术的应用&#xff0c;更是一项战略必需。许多企业若因目标不明确、数据准备不足或与业务重点脱节而未能有效利用AI技术&#xff0c;可能面临严重后果&#xff0c;包括高级网络威胁数量的激增。 AI准备的核心要素 构建稳健的网络安全…...

《重构全球贸易体系用户指南》解读

文章目录 背景核心矛盾与理论框架美元的“特里芬难题”核心矛盾目标理论框架 政策工具箱的协同运作机制关税体系的精准打击汇率政策的混合干预安全工具的复合运用 实施路径与全球秩序重构阶段性目标 风险传导与反制效应内部失衡加剧外部反制升级系统性风险 范式突破与理论再思考…...

MacOs下解决远程终端内容复制并到本地粘贴板

常常需要在服务器上捣鼓东西&#xff0c;同时需要将内容复制到本地的需求。 1-内容是在远程终端用vim打开&#xff0c;如何用vim的类似指令达到快速复制到本地呢&#xff1f; 假设待复制的内容&#xff1a; #include <iostream> #include <cstring> using names…...

基于PAI+专属网关+私网连接:构建全链路 Deepseek 云上私有化部署与模型调用架构

DeepSeek - R1 是由深度求索公司推出的首款推理模型&#xff0c;该模型在数学、代码和推理任务上的表现优异&#xff0c;市场反馈火爆。在大模型技术商业化进程中&#xff0c;企业级用户普遍面临四大核心挑战&#xff1a; 算力投入成本高昂&#xff1a;构建千亿参数级模型的训…...

【cocos creator 3.x】cocos creator2.x项目升级3.x项目改动点

1、基本改动 基本改动&#xff1a;去掉了cc.&#xff0c;改成在顶部添加导入 项目升级时候直接将cc.去掉&#xff0c;根据提示添加引用 node只保留position,scale,rotation,layer 其余属性如opacity&#xff0c;如果需要使用需要在节点手动添加UIOpacity组件 3d层和ui层分开…...

​​eBay东南亚爆单密码:72小时交付计划如何重构厦门仓+东南亚供应链?​

2024年东南亚电商市场规模预计突破2340亿美元&#xff0c;年复合增长率达18%。eBay最新战略将厦门纳入海外仓核心节点&#xff0c;推出“72小时交付计划”&#xff0c;通过“仓配转”一体化链路&#xff0c;助力中国卖家实现东南亚市场订单履约率提升10%&#xff0c;退货成本降…...

List基础与难度题

1. 向 ArrayList 中添加元素并打印 功能描述&#xff1a; 程序创建一个空的 ArrayList 集合&#xff0c;用于存储字符串类型的元素。向该 ArrayList 中依次添加指定的字符串元素。使用增强型 for 循环遍历 ArrayList 中的所有元素&#xff0c;并将每个元素打印输出到控制台。 …...

Oracle19C低版本一天遭遇两BUG(ORA-04031/ORA-600)

昨天帮朋友看一个系统异常卡顿的案例&#xff0c;在这里分享给大家 环境&#xff1a;Exadata X8M 数据库版本19.11 1.系统报错信息 表象为系统卡顿&#xff0c;页面无法刷出&#xff0c;登陆到主机上看到节点1 系统等待存在大量的 cursor: pin S wait on X等待 查看两个节…...

golang处理时间的包time一次性全面了解

本文旨在对官方time包有个全面学习了解。不钻抠细节&#xff0c;但又有全面了解&#xff0c;重点介绍常用的内容&#xff0c;一些低频的可能这辈子可能都用不上。主打一个花最少时间办最大事。 Duration对象: 两个time实例经过的时间,以长度为int64的纳秒来计数。 常见的durati…...

C++学习:六个月从基础到就业——面向对象编程:重载运算符(下)

C学习&#xff1a;六个月从基础到就业——面向对象编程&#xff1a;重载运算符&#xff08;下&#xff09; 本文是我C学习之旅系列的第十三篇技术文章&#xff0c;是面向对象编程中运算符重载主题的下篇。本篇文章将继续深入探讨高级运算符重载技术、特殊运算符、常见应用场景和…...

【网络安全】谁入侵了我的调制解调器?(二)

文章目录 针对 TR-069 协议 REST API 的攻击思路攻击百万台调制解调器意外发现 Cox 后端 API 的授权绕过漏洞确认我们能够进入任何人的设备访问和更新任何Cox商业客户账户通过泄露的加密密钥覆盖任何人的设备设置执行对任何调制解调器的命令影响最后想说阅读本文前,请先行浏览…...

【4.1.-4.20学习周报】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 摘要Abstract一、方法介绍1.1HippoRAG 1.2HippoRAG2二、实验2.1实验概况2.2实验代码2.3实验结果 总结 摘要 本博客介绍了论文《From RAG to Memory: Non-Parametri…...

MySQL 临时表介绍

在 MySQL 数据库中&#xff0c;临时表是一种特殊类型的表&#xff0c;它在数据库会话期间存在&#xff0c;会话结束时自动删除。临时表为处理特定的、临时性的数据操作任务提供了一种高效且便捷的方式。 一、临时表的创建 使用CREATE TEMPORARY TABLE语句来创建临时表。其语法…...