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

QT网页 webengine / CEF

QT + WebEngine

官方文档

WebEngine 架构:

在这里插入图片描述

能看到 WebEngine 有一个核心模块是基于 Chromium 构造的,通过使用 Chromium 的Blink渲染引擎和V8 JavaScript引擎来处理和渲染Web内容,并将这些底层技术封装为一系列高级的C++类和接口,以便开发者可以将Web内容嵌入到Qt应用程序中。

  1. WebEngine Widgets 模块:主要是针对于桌面应用,提供了用于将Web内容嵌入到Qt应用程序中的窗口和小部件, 可以用于各种应用程序来加载web内容。
    在这里插入图片描述

主要架构如上图所示,主要提供了一些组件:

  • QWebEnginePage:一个代表Web页面的类,它包含了页面的内容、状态和功能。它可以执行JavaScript代码、处理表单、捕获页面截图等。
  • QWebEngineView:一个用于展示Web页面的小部件,它是QWebEnginePage的可视化容器。它可以加载URL、导航历史、缩放页面等。
  • QWebEngineProfile:一个表示浏览器配置文件的类,它包含了缓存、Cookie和安全策略等设置。它可以用于实现多用户浏览器或隐私浏览功能。
  • QWebEngineSettings:一个表示浏览器设置的类,它包含了字体、颜色、JavaScript和插件等选项。它可以用于调整页面的渲染效果和功能。
  • QWebEngineScript:执行 JavaScript 脚本的类,用于向网页中注入并执行自定义的 JavaScript 脚本来添加新功能或修改现有的功能。
  • QWebEngineHistory:管理浏览历史的类,它提供了对浏览历史记录的访问和操作,其中每个历史记录项都由 QWebEngineHistoryItem 类表示。
  • WebEngineAction:表示对网页的操作,由WebEngineView::action()方法返回,包含相关的一些信息;

一个QWebEngineView 实例有一个 QWebEnginePage. QWebEnginePage有一个QWebEngineHistory和一些用于操作页面的QAction对象。每一个QWebEnginePage都属于一个QWebEngineProfile, QWebEngineProfile有一个页面设置的QWebEngineSettings, 一个在页面上运行脚本的QWebEngineScriptCollection, 一个访问HTTP cookies的QWebEngineCookieStore。

  1. WebEngine 模块:主要是针对用于QML。
    Qt WebEngine 除了没有单独访问的web引擎页面,包含的其他组件与Qt WebEngine Widgets相同,功能也是一致的。

  2. WebEngine Process:这是可执行文件,对应的是一个独立的用于渲染网页和执行JavaScript进程,用于增强安全性与内存隔离。
    网上有文章说“每个QWebEngineView或WebEngineView实例都会启动一个QtWebEngineProcess.exe进程”,在View对象过多的情况下会导致内存占用;
    但是在官方文档里没有找到相关描述,这个问题暂时未能确定;

  3. WebEngine 对 AMD 显卡支持性不好,在某些A系显卡下会显示不出来甚至闪退; 后续优化计划目前还没在网上搜到;另外嵌入的网页无法播放视频,要播放视频的话需要下载QT源码自己设置编译参数集成视频播放库;

  4. 对显卡有依赖,基于openGL,看网上说如果在显卡和显卡驱动不一致或是旧版版本下还有openGL,程序有可能出异常

QT 与 网页通信

  1. 通过 WebEnginePage 与网页通信
    通过 WebEngine 嵌入网页的方式与网页端的JS交互很容易,QWebEnginePage 自带了一个函数为 runJavaScript ,这个函数可以直接通知 JS 执行指定的函数,
    void QWebEnginePage::runJavaScript(const QString &scriptSource, const std::function<void (const QVariant &)> &resultCallback)

例如这个接口,第一个参数就是要调用的接口以及参数拼成的字符串,第二个参数是对应的回调。
这种方式用起来很方便,但是是单向的

  1. QWebChannel 双向通信
    QT提供了一种通道机制,可以让 JS 与 QT 通过对象建立连接, 然后进行通信;
    QWebChannel 提供了在 QT 和 HTML/JS 之间点对点的通信能力,通过向 HTML/JS 端的 QWebChannel 发布 QObject 的 派生对象,进而实现在 HTML/JS 端可以同步读取来自 Qt 端的 公共插槽 和 QObject 的 属性值 和 方法。在整个通信过程中,无需任何手动序列化传入的参数。所有 Qt 端的数据更新,都会自动且异步的触发 signal 并更新到 client 端。这个机制一般被称为对象模型,QObject 是这个模型的核心,而模型实现的基础就是靠的 QT 的 signal 和 slot 也就是信号槽机制。

这个机制主要分以下几步:

  • QT端 创建 HTML/JS 网页
  • JS端 创建 channel 对象,通过 channel 取到通信对象 QObject;
  • QT端 创建 channel 对象与通信用的 QObject 对象;
  • QT端 channel 与 网页对应的 QWebEngineView 绑定;
  • QT端 将 channel 与 QObject 对象绑定;
  • QT端/JS端 修改QObject属性,另一端对应的监听函数响应;

WebEngine 网页示例

源码见 QTWebtest_WebEngine
在示例代码里,我写了一个中间类名为 JS2QTBridge, 里面定义了两个字符串 m_jscontent 与 m_content;
通过 channel 将这个对象对 JS 与 QT 双向绑定,网页/QT界面上显示内容发生改变时给 QT/JS 发送对应信号,实现效果如:
在这里插入图片描述

其中在QT上点击按钮通知网页画图是用 runJavaScript 方法实现;
在网页点击饼图在QT弹出提示是通过调用 bridge 对象的函数实现;
两边输入框修改另一侧的显示区域一同变化是通过对 bridge 对象的成员变量与界面控件信号槽绑定实现;

QT + cef

CEF3使用多个进程运行。处理窗口创建、绘制和网络访问的主要进程称为浏览器进程,通常与宿主应用程序的进程相同,大多数应用程序的逻辑将在浏览器进程中运行。使用Blink引擎渲染HTML和JavaScript在单独的渲染进程中,相关的应用程序逻辑(如JavaScript绑定和DOM访问)将在渲染进程中运行。默认进程模型将为每个唯一源地址(scheme+domain)运行一个新的渲染进程。其他进程将根据需要生成,例如处理Flash等插件的插件进程和处理加速合成的GPU进程。另外浏览器进程中会进行窗口绘制,不是绘制HTML内容,而是承载网页内容的那个窗体,渲染进程则不会用来创建窗体。

<!-- 编译CEF参考 cef.md – >
cef解决方案中有多个工程:

  • ALL_BUILD与ZERO_CHECK:是cmake自动生成的辅助工程。
  • cef_gtest与ceftests:都是测试模块,这里不关心。
  • cefclient:一个包含CEF各种API演示的浏览器程序Demo。
  • cefsimple:一个简单的CEF浏览器程序Demo。
  • libcef_dll_wrapper:对libcef库的C++代码封装。上述cefclient与cefsimple都会用它。

可以移植 cefsimple 来实现一个简单的浏览器程序:

  • simple_app.h、simple_app.cc、simple_handler.h、simple_handler.cc 这四个文件拷到QT工程中;
  • simple_handler.h中的 PlatformTitleChange 定义注释掉;simple_handler.cc 的 OnTitleChange 对这个函数的调用也注释掉;
  • CEF.lib等相关库 以及 libcef_dll_wrapper.lib 拷贝到工程中,链接到QT工程里;
  • CEF的include文件夹拷贝到QT工程位置并引入;
  • CEF的 Resources 中的五项拷贝到QT编译出来的EXE的环境里;这些是网页渲染引擎需要的资源,不打包过去程序运行时会报错:icu_util.cc(224)] Invalid file descriptor to ICU data received.

QT 与 CEF 嵌入的网页通信有两种方式;

1. 使用 QWebChannel

这种方法与上面使用 webengine 时类似, 在QT 与 JS中声明channel, 通过将这个channel对象来作为中间通信的桥梁;
这种方式有一个优点是,可以通过 websocket 来让 Channel 监听指定的IP和端口来实现远程通信,而不仅仅局限于QT与它启动的web子进程;

2. 通过 CefRenderProcessHandler 的方法回调传递

  • virtual void OnWebKitInitialized() {}
    当 webkit 初始化完毕之后。在这个函数中,可以通过 CefRegisterExtension() 函数来注册JavaScript与C++代码之间的“映射”关系,官方管这种方式叫做扩展(Extension)

  • virtual void OnContextCreated(CefRefPtr browser, CefRefPtr frame, CefRefPtr context) {}
    JavaScript 上下文被创建以后,在这个函数中,可以为JavaScript中的 window 对象绑定属性和方法,官方将这种方式叫做 窗口绑定(window binding)

3. CEF网页通信示例

源码见 QTWebtest_CEF
在示例代码里,我写了一个网页,将这个网页用CEF展示在了QT窗口中,然后另外打开了一个QT对话框;
通过 channel 来在网页与对话框之间发送信息,展示效果如下:
在这里插入图片描述

CEF使用的一些问题:
不支持视频,需要自编译源码;原生的CEF是纯C代码,libcef_dll_wrapper才是在CEF的基础上封装的C++ API;
很大,我使用的版本的 libcef.dll 164MB, libcef_dll_wrapper.lib 33MB ,还有一些相关的加一起超200MB;
MD/MT属性支持的不好,CEF工程默认使用的是MT,其中用到的一些依赖库如cef_sandbox.lib都是MT编译的,使用MD编译会报错,要是改成MD需要自己下载相关源码编译;
多进程架构,WebEngine应该是一个view一个进程,如果只有一个view然后路径切换不会增加新的进程,CEF应该是每打开一次网页就会创建一个渲染进程;

相关文章:

QT网页 webengine / CEF

QT WebEngine 官方文档 WebEngine 架构&#xff1a; 能看到 WebEngine 有一个核心模块是基于 Chromium 构造的&#xff0c;通过使用 Chromium 的Blink渲染引擎和V8 JavaScript引擎来处理和渲染Web内容&#xff0c;并将这些底层技术封装为一系列高级的C类和接口&#xff0c;以…...

Golang笔试题:编写一个函数,接收一个整数参数n,输出n的阶乘结果

今天&#xff0c;我们开发的AI笔试题工具&#xff0c;ai扁食——AI程序员笔试系统给我出了中级Golang题目&#xff0c;就是这道题&#xff1a;《请编写一个函数&#xff0c;接收一个整数参数n&#xff0c;输出n的阶乘结果》&#xff0c;希望我写一个函数&#xff0c;输出n的阶乘…...

外包干了2个月,技术退步明显.......

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入武汉某软件公司&#xff0c;干了接近4年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了四年的功能测试…...

无涯教程-JavaScript - BINOM.DIST函数

描述 BINOM.DIST函数返回单个项二项式分布概率。 在具有固定数量的测试或试验的问题中使用BINOM.DIST。 当任何试验的输出只是成功或失败时 试验是独立的,并且 在整个实验中成功的概率不变的情况 语法 BINOM.DIST (number_s,trials,probability_s,cumulative)争论 Argu…...

linux定时重启tomcat

1.编辑重启Tomcat命令 首先编辑一个文件 vi my_restart.sh 然后输入&#xff1a; #!/bin/bash . /etc/profile tomcatPath"/opt/finereport/tomcat" binPath"$tomcatPath/bin" echo "[info][$(date %F %H:%M:%S)]正在监控tomcat&#xff0c;路径&a…...

在静态方法中访问@Value注入的静态变量!!

一、 静态变量 static修饰的成员变量&#xff0c;称为静态成员变量&#xff0c;静态成员变量最大的特性&#xff1a;不属于某个具体的对象&#xff0c;是所有对象所共享的 简单来说&#xff1a;在某些类的对象中存在一些相同的成员变量&#xff0c;那么这种成员变量就可以设置…...

掌握这些算法,让你的编程之路更顺畅——重要算法解析

一个程序员一生中可能会邂逅各种各样的算法&#xff0c;但总有那么几种&#xff0c;是作为一个程序员一定会遇见且大概率需要掌握的算法。这些算法通常被广泛应用于日常编程工作中&#xff0c;是提升编程效率和解决实际问题的重要工具。本文将介绍几种十分重要的“必抓&#xf…...

flink集群与资源@k8s源码分析-总述

1 简介 集群和资源模块提供动态资源能力,是分布式系统关键基础设施,分布式datax,分布式索引,事件引擎都需要集群和资源的弹性资源能力,提高伸缩性和作业处理能力。本文分析flink的集群和资源的k8s模块,深入了解其设计原理,为开发自有的集群和资源组件做技术准备, 同时涉…...

LeetCode 0213. 打家劫舍 II:动动态规划

【LetMeFly】213.打家劫舍 II&#xff1a;动动态规划 力扣题目链接&#xff1a;https://leetcode.cn/problems/house-robber-ii/ 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋&#xff0c;每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 &#xff0c;这意味…...

VMware17 不可恢复错误mks解决方案

用的虚拟机VMware17版本&#xff0c;然后运行带HDR的unity程序&#xff0c;结果报错 网上找了很多解决方案&#xff0c;都没用。毕竟需要在不放弃虚拟机3D加速的情况下运行。 最终皇天不负有心人&#xff0c;亲测有效的方法&#xff1a; 在虚拟机名字.vmx文件里添加以下2行&a…...

【深度学习】 Python 和 NumPy 系列教程(廿五):Matplotlib详解:3、多子图和布局:subplot()函数

目录 一、前言 二、实验环境 三、Matplotlib详解 1、2d绘图类型 2、3d绘图类型 3、多子图和布局 1. subplot()函数 简单示例 一、前言 Python是一种高级编程语言&#xff0c;由Guido van Rossum于1991年创建。它以简洁、易读的语法而闻名&#xff0c;并且具有强大的功能…...

计算机网络知识补充(1)

计算机网络:是一个将分散的&#xff0c;具有独立功能的计算机系统&#xff0c;通过通信设备和线路进行连接起来&#xff0c;由功能完善的软件实现资源共享和信息共享的系统&#xff0c;计算机网络是互连的&#xff0c;自治的计算机集合 互连:通过通信链路来进行互联互通 自治:没…...

C# Onnx Yolov8 Pose 姿态识别

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System…...

7.algorithm2e中while怎么使用

algorithm2e中while怎么使用 在 algorithm2e 宏包中&#xff0c;要使用 while 循环&#xff0c;您可以使用 \While 和 \EndWhile 命令来定义循环的开始和结束。以下是如何使用 while 循环的示例&#xff1a; \documentclass{article} \usepackage[linesnumbered,boxed]{algorit…...

Flask狼书笔记 | 08_个人博客(下)

文章目录 8 个人博客8.4 初始化博客8.5 使用Flask-Login管理用户认证8.6 CSRFProtect实现CSRF保护8.7 编写博客后台小结 8 个人博客 8.4 初始化博客 1、安全存储密码 密码不要以明文的形式直接存储在数据库中&#xff0c;以防被攻击者盗取、泄露。一般的做法是&#xff0c;不…...

机器学习第十课--提升树

一.Bagging与Boosting的区别 在上一章里我们学习了一个集成模型叫作随机森林&#xff0c;而且也了解到随机森林属于Bagging的成员。本节我们重点来学习一下另外一种集成模型叫作Boosting。首先回顾一下什么叫Bagging? 比如在随机森林里&#xff0c;针对于样本数据&#xff0c;…...

react scss.modules中使用iconfont

全局引入详见全局引入scss 全局的scss文件中引入iconfont.css use "../font/iconfont.css"; 然后就可以正常使用啦...

使用Jmeter+ant进行接口自动化测试(数据驱动)

最近在做接口测试&#xff0c;因为公司有使用jmeter做接口测试的相关培训资料&#xff0c;所以还是先选择使用jmeter来批量管理接口&#xff0c;进行自动化测试。话不多说&#xff0c;进入正题&#xff1a; 1.使用csv文件保存接口测试用例&#xff0c;方便后期对接口进行维护&…...

可视化图表组件之股票数据分析应用

股市是市场经济的必然产物&#xff0c;在一个国家的金融领域之中有着举足轻重的地位。在过去&#xff0c;人们对于市场走势的把握主要依赖于经验和直觉&#xff0c;往往容易受到主观因素的影响&#xff0c;导致决策上出现偏差。如今&#xff0c;通过数据可视化呈现&#xff0c;…...

STM32 ~ GPIO不同模式之间的区别与实现原理

GPIO全称General Purpose Input Output &#xff0c;即通用输入/输出。其实GPIO的本质就是芯片的一个引脚&#xff0c;通常在ARM中所有的I/O都是通用的。不过&#xff0c;由于每个开发板上都会设计不同的外围电路&#xff0c;这就造成了GPIO的功能可能有所不同。大部分GPIO都是…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...