基于Qt WebEngine 的Web仪器面板GUI程控技术

news2024/9/26 3:25:10

随着IIoT的发展,很多工业仪器也具备了远程管理的GUI。与早期使用串口进行命令交互不同,这些GUI可以直接在远程呈现数据。

作为希望对仪器、软件进行二次开发的小公司来说,会遇到GUI人工操作转自动化的需求。在无法通过串口等传统接口进行自动操作的情况下,就只能考虑GUI自动化。在现场工程师领域,常见的GUI自动化程控技术主要分native界面与Web界面两类。

  1. Native窗体(如具备X-Window Form界面的仪器,Qt等)。使用鼠标模拟点击、Hook等技术,在仪器的OS内部,用自己的APP实现模拟键盘、读取控件并填写数据。
  2. Web 自动化交互(Web页面仪器)。使用自建浏览器打开操作界面,使用JS操作页面元素,实现交互(本文)。

当然,还有一类非常特殊的极端情况,就是对物理开关的继电器操作。使用继电器取代按键,并通过解析LED七段编码,做到按键与显示的反馈控制。这种情况需要动用烙铁,已经不是编程能解决的问题了。

由于现代Web页面可以通过JS操作,理论上只要有一个支持JS控制接口的浏览器就能完成GUI自动化操作。不过,一般的浏览器二次开发,需要配置的依赖还是很多的。Qt WebEngine 是Qt Webkit的继承者。这个模块允许使用非常简单的代码进行GUI程控。

1. 分析页面的构成

使用firefox或者chrome浏览器打开管理页面,击打 F12 开启调试页面,在查看器中可以找到控件。
PASS

要在浏览器内核的JS Runtime里使用这个控件,有几种方法。

  1. 使用ID直接访问。比如上图的控件,有本身的ID叫做 lgPwd,因此直接可以使用ID引用
>> lgPwd
<input id="lgPwd" name="password" type="password" maxlength="32">

>> lgPwd.value="123456";
"123456"
  1. 使用CSS选择器访问
    右键单击上图查看器右侧的选中控件部分,复制CSS选择器
    在这里插入图片描述
    则可以在JS里用运算 $()访问。
>> $('#lgPwd')
Object { 0: input#lgPwd, length: 1, context: HTMLDocument http://192.168.1.1/, selector: "#lgPwd" }

>> $('#lgPwd')[0]
<input id="lgPwd" name="password" type="password" maxlength="32">

>> $('#lgPwd')[0].value
"123456" 
  1. 使用xPath定位
    右键单击上图查看器右侧的选中控件部分,复制XPath选择器
    在这里插入图片描述
    而后用 $x拾取语法来枚举控件,在返回的数组里获得想要的东西。
>> $x('//*[@id="lgPwd"]')
Array [ input#lgPwd ]

>> $x('//*[@id="lgPwd"]')[0]
<input id="lgPwd" name="password" type="password" maxlength="32">

>> $x('//*[@id="lgPwd"]')[0].value='234';
"234"
>> $x('//*[@id="lgPwd"]')[0].value
"234" 

需要控制的控件、读取的控件一旦可以在控制台访问,即可转入下面的步骤了。为什么不直接在Chrome中使用JS脚本运行,或者在Python里通过remote操作和Chrome console来互动呢?显然我们希望自己的程序显得比较完整,给用户一个“本地”应用程序的观感。上面的例子使用的是路由器的登入界面,实际仪器的登入界面比这个页面要复杂。

2. 配置Qt WebEngine

刚才我们说了,希望把仪器的管理页面带到自己的GUI上,作为一个子页面运行。这样,仪器“看起来”运行在我们的程序中。要完成这样的操作,可以使用Qt WebEngine. 可能有读者有疑惑,用WebKit可以吗? 理论上是可以的。只是WebKit已经从Qt的官方支持里去掉了。经过实验,Qt Webkit 对一些新JS特性支持的一般,而WebEngine却非常流畅,即使是实时的图形刷新,也不在话下。

在Windows下使用QWebEngine,只能使用 MS Visual C++编译器。这是Qt WebEngine的一大遗憾。受制于chromium的编译器兼容性问题, MINGW 是不被支持的。好在无论是VC还是Qt,都有开源版本,在线安装速度也不差。我们使用Qt的在线安装,别忘了勾选“Qt WebEngine”选项(默认不装)

在这里插入图片描述
同时,确保安装了对应的 VC2019或其他版本的编译器。

3 程序开发

QWebEngine 与老的Webkit相比,操作大部分都是异步的。但它的API设置的比较好用。如果需要迅速实现复杂功能,可以直接把例子simple_browser的框架全部集成到自己的程序中,再进行一定的裁剪。如果只是要操作固定的页面,则可以直接集成。

首先,在模块中引入 webenginewidgets

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets webenginewidgets

CONFIG += c++17

最为简单的方法,是拖入一个QWebEngineView,如果没有designer扩展,则拖入Widget,提升为这个类。

提升
这样,我们即可在代码中获得浏览器实例:

ui->web->load(QUrl("http://192.168.1.122"));

当需要填写控件、获取返回值时,只需要运行:

	ui->web->page()->runJavaScript(
				"lgPwd.value=\"123456\";",
				[](const QVariant & result)->void{
		qDebug()<<result;
	});

输出

QVariant(QString, "123456")

实际应用中,通过获取网页的状况,并根据外部环境调整界面控件的取值,能够实现完整的反馈控制。一种典型的场景是根据环境检测仪器的输出,直接控制车间顶棚伸缩杆的开启与关闭。当然,更为复杂的场景需要进行调试。

4. 调试

QWebEngine可以方便的启用进程内调试器,

void WidgetWCtrl::on_pushButton_debug_clicked()
{
	QWebEngineView * v = new QWebEngineView(this);
	ui->web->page()->setDevToolsPage(v->page());
	v->show();
	ui->tabWidget->addTab(v,"DEV");
}

此时,我们自己的程序里立刻也引入了Web开发工具:

开发工具

5. 发布

要发布程序,需要把EXE拷贝出来到独立文件夹,在cmd命令行下,运行windeployqt:

C:\> C:\Qt\6.4.2\msvc2019_64\bin\windeployqt.exe --compiler-runtime C:\projects\WebCtrlBIN\WebCtrl.exe
C:\projects\WebCtrlBIN\WebCtrl.exe 64 bit, release executable
Adding Qt6Svg for qsvgicon.dll
...
C:\>

此时,文件夹里就有了所有运行时需要的文件:
Files
要注意的是,除了我们自己的EXE,还多了一个QtWebEngineProcess.exe,这就是QWebEngine的后台进程。

和QtWebKit不同,这个框架背后还是需要一个独立的可执行文件的支持。

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

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

相关文章

nextjs开发 + vercel 部署 ssr ssg

前言 最近想实践下ssr 就打算用nextjs 做一个人博客 &#xff0c; vercel 部署 提供免费域名&#xff0c;来学习实践下ssr ssg nextjs 一个轻量级的react服务端渲染框架 vercel 由 Next.js 的创建者制作 支持nextjs 部署 免费静态网站托管 初始化项目 npx create-next-app p…

【Linux】目录结构

Linux世界里&#xff0c;一切皆文件。 /bin&#xff1a;是Binary的缩写&#xff0c;这个目录存放着最经常使用的命令。&#xff08;常用&#xff09; /sbin&#xff1a;s就是Super User的意思&#xff0c;这里存放的是系统管理员使用的系统管理程序。 /home&#xff1a;存放普…

关于Pytorch中的张量学习

关于Pytorch中的张量学习 张量的概念和创建 张量的概念 Tensor是pytorch中非常重要且常见的数据结构&#xff0c;相较于numpy数组&#xff0c;Tensor能加载到GPU中&#xff0c;从而有效地利用GPU进行加速计算。但是普通的Tensor对于构建神经网络还远远不够&#xff0c;我们需…

实力加持!RestCloud完成多方国产化适配,携手共建信创生态

近年来&#xff0c;随着数字化建设进入深水区&#xff0c;企事业单位对信息安全重视程度与日俱增&#xff0c;核心技术自主可控已成为时代呼唤&#xff0c;国产化浪潮日益汹涌澎湃。近日&#xff0c;RestCloud在国产化方面取得新进展&#xff0c;完成了全部产品线信创环境的多方…

系统重装漏洞

zzcms系统重装漏洞 一、配置zzcms环境 1. 使用小皮搭建zzcms框架 2. 安装zzcms 按照下面的操作进行,傻瓜式操作即可 3. 打开网站 二、漏洞利用 在访问install目录的默认文件后,会出现zzcms安装向导 http://www.zzcms.com/install/index.php 但是会显示 “安装向导…

MQTT协议-发布消息(客户端向服务器发送)

MQTT协议-发布消息&#xff08;客户端向服务器发送&#xff09; 发布消息报文组成&#xff1a;https://blog.csdn.net/weixin_46251230/article/details/129414158 在分析完服务器下发到客户端的报文后&#xff0c;就可以参考JSON格式的有效载荷&#xff0c;将温湿度的值改为…

Linux发行版的backport

遇到一个问题,简要记录如下: base on ubuntu18.06 4.15内核,这版内核不支持一款intel的集成网卡,追踪内核代码的提交历史才发现,这款网卡是从linux-4.20才开始支持的,系统自带的这个Kernel版本不支持。 如果不允许升级内核,面对这种问题,社区的做法是把新内核的特性cher…

顺序表【数据结构】

文章目录:star2:1. 顺序表概念:star2:2. 框架3. 基本功能3.1 头文件:star:3.2 初始化:star:3.3 扩容:star:3.4 打印:star:3.5 尾插:star:3.6 头插:star:3.7 尾删:star:3.8 头删:star:3.9 指定插入:star:3.10 指定删除:star:3.11 查找:star2:3.12 注意事项4. 顺序表的缺点&#…

云原生安全2.X 进化论系列|云原生安全2.X未来展望(4)

随着云计算技术的蓬勃发展&#xff0c;传统上云实践中的应用升级缓慢、架构臃肿、无法快速迭代等“痛点”日益明显。能够有效解决这些“痛点”的云原生技术正蓬勃发展&#xff0c;成为赋能业务创新的重要推动力&#xff0c;并已经应用到企业核心业务。然而&#xff0c;云原生技…

Git学习笔记(六)-标签管理

发布一个版本时&#xff0c;我们通常先在版本库中打一个标签&#xff08;tag&#xff09;&#xff0c;这样&#xff0c;就唯一确定了打标签时刻的版本。将来无论什么时候&#xff0c;取某个标签的版本&#xff0c;就是把那个打标签的时刻的历史版本取出来。所以&#xff0c;标签…

销售使用CRM系统集成Excel的五个技巧

销售过程中有很多情况会降低团队的效率。通过正确的实施CRM客户管理系统&#xff0c;可以帮助您的企业自动执行手动任务、减少错误并专注于完成交易。这里有5个技巧&#xff0c;可以帮助您的销售人员通过CRM集成Excel为销售流程赋能并提高他们的整体效率。 技巧1&#xff1a;将…

Python每日一练(20230309)

目录 1. 删除有序数组中的重复项 ★ 2. 二叉树的最小深度 ★★ 3. 只出现一次的数字 II ★★ &#x1f31f; 每日一练刷题专栏 C/C 每日一练 ​专栏 Python 每日一练 专栏 1. 删除有序数组中的重复项 给你一个有序数组 nums &#xff0c;请你原地删除重复出现的元素…

Xuetr杀毒工具使用实验(28)

实验目的 &#xff08;1&#xff09;学习Xuetr的基本功能&#xff1b; &#xff08;2&#xff09;掌握Xuetr的基本使用方法。预备知识 windows操作系统的基本知识如&#xff1a;进程、网络、服务和文件等的了解。 XueTr是近年推出的一款广受好评的ARK工具。ARK工具全称为Anti R…

Ubuntu20.04中Docker安装与配置

一、安装 1、卸载可能存在的旧版本 sudo apt-get remove docker docker-engine docker-ce docker.io2、更新apt包索引 sudo apt-get update显示“正在读取软件包列表… 完成” 3、安装以下包以使apt可以通过HTTPS使用存储库(repository) sudo apt-get install -y apt-tran…

java多线程(二三)并发编程:Callable、Future和FutureTask

一、Callable 与 Runnable 先说一下java.lang.Runnable吧&#xff0c;它是一个接口&#xff0c;在它里面只声明了一个run()方法&#xff1a; public interface Runnable {public abstract void run(); }由于run()方法返回值为void类型&#xff0c;所以在执行完任务之后无法返…

关于React Hook(18)

useState&#xff08;&#xff09;&#xff1a;&#x1f449;详情 &#xff08;必须“有条件地调用”&#xff1b;注意避免冗余状态的产生&#xff09; 关于useState的两种使用方式的区别&#xff1a;&#x1f449;详情 关于batch机制&#xff1a;有条件地调用一些状态的set方…

L3-021 神坛

在古老的迈瑞城&#xff0c;巍然屹立着 n 块神石。长老们商议&#xff0c;选取 3 块神石围成一个神坛。因为神坛的能量强度与它的面积成反比&#xff0c;因此神坛的面积越小越好。特殊地&#xff0c;如果有两块神石坐标相同&#xff0c;或者三块神石共线&#xff0c;神坛的面积…

STM32F103R8T6 SPWM实现正弦波输出

前言 PWM合成正弦波&#xff0c;原理什么的不详细说了&#xff0c;概括一下就是 PWM有效面积的积分 正弦波的有效面积。PWM的频率越快&#xff0c;细分的越多&#xff0c;锯齿也就越不明显。 做法是&#xff1a;首先利用正弦波取点软件&#xff0c;取点1000个&#xff0c;生…

计算机网络:OSPF协议和链路状态算法

OSPF协议 开放最短路经优先OSPF协议是基于最短路径算法SPF,其主要特征就是使用分布式的链路状态协议OSPF协议的特点&#xff1a; 1.使用泛洪法向自治系统中的所有路由器发送信息&#xff0c;即路由器通过输出端口向所有相邻的路由器发送信息&#xff0c;而每一个相邻的路由器又…

阶段二12_面向对象高级_继承3

知识点内容&#xff1a; 抽象类 模板设计模式 final关键字 一.抽象类 (1)抽象类概述 抽象方法&#xff1a;将共性的行为&#xff08;方法&#xff09;抽取到父类之后&#xff0c;发现该方法的实现逻辑 无法在父类中给出具体明确&#xff0c;该方法就可以定义为抽象方法。 抽…