PySide2 QWebEngine与Web js交互

news2024/11/27 22:37:49

文章目录

  • 单向交互
  • 双向传值
  • 案例

单向交互

QWebEngineView加载web页面,web页面中点击按钮,执行js代码,js的返回值传给QWebEnginePage,使用python进行保存结果。
单向,js向python(PySide2)端传输数据。

  1. 前端实现
<!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">
    <link rel="stylesheet" href="index.css">
    <title>单向传值</title>
</head>
<body>
    <button id="btn" onclick="jsFunc()">测试单向传值</button>
    <script type="text/javascript">
        function jsFunc(){
            let data1 = 20;
            let data2 = "js transport value to python"
            let data3 = {
                origin: "javascript",
                target: "python"
            }
            // js将数据打印出来
            console.log("js打印:", data1) // 打印出来
            console.log("js打印:", data2)
            console.log("js打印:", data3)
        }

    </script>
</body>
</html>

使用Live Server启动服务器,加载html页面。
VS code 中安装Live server 插件;
alt+l; alt+o 启动;或者右键-Open With Live Server
 
2. PySide2 Qt端实现


from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWebEngineWidgets import QWebEnginePage, QWebEngineView, QWebEngineProfile


# 自定义页面类
class MyWebEnginePage(QWebEnginePage):
    def javaScriptConsoleMessage(self, level:QWebEnginePage.JavaScriptConsoleMessageLevel, 
                                 message:str, lineNumber:int, sourceID:str):
        # 接收js控制台 打印的信息
        print("接收js数据:", message)
        # 保存的动作
        return super(MyWebEnginePage, self).javaScriptConsoleMessage(level, message, lineNumber, sourceID)


# 自定义web引擎类
class MyWebEngineView(QWebEngineView):
    def __init__(self):
        QWebEngineView.__init__(self)
        self.setPage(MyWebEnginePage(self))
        

class MyWindow(QWidget):
    def __init__(self, title="laufing"):
        super(MyWindow, self).__init__()
        # 窗口的尺寸及居中
        self.resize(800, 600)
        desk = QDesktopWidget().geometry()
        width, height = desk.width(), desk.height()
        self.move(width//2 - self.width()//2, height//2 - self.height()//2)

        # 窗口标题
        self.setWindowTitle(title)
        self.setWindowIcon(QIcon("./imgs/dog.jpg"))

        #
        self.set_ui()

    def set_ui(self):
        vb = QVBoxLayout(self)
        self.web_view = MyWebEngineView()
        vb.addWidget(self.web_view)

        # 加载页面
        self.web_view.page().load(QUrl("http://127.0.0.1:5500/testWeb/test.html"))


if __name__ == '__main__':
    import sys
    # 创建应用程序
    app = QApplication(sys.argv)

    win = MyWindow("测试可视化")
    win.show()

    # 进入消息循环
    sys.exit(app.exec_())

在这里插入图片描述
只能单向传递数值、字符串,对象必须json序列化才可以传递。
 

双向传值

Qt 与javascript 双向传值,需要借助qwebchannel.js 工具。

  1. 前端index.html
<!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">
    <link rel="stylesheet" href="index.css">
    <title>Document</title>
</head>
<body>
    <button id="btn" onclick="jsFunc()">向python传值</button>
    <button onclick="getValue()">获取python值</button>

    <!-- 加载qwebchannel.js -->
    <script src="qwebchannel.js"></script>

    <script type="text/javascript">

        // 页面加载完成,执行函数
        window.addEventListener("DOMContentLoaded", function(){
            // 创建Webchannel,与 Qt 端建立连接
            // qt.webChannelTransport 不用管,自动传过来
            new QWebChannel(qt.webChannelTransport, function(channel) {

                // 通过channel 获取Qt端的对象
                window.pyObj = channel.objects.lauf;
                
                // Qt对象的note信号 连接到js的函数
                window.pyObj.note.connect(function(arg){
                        alert("qt信号触发js函数: ", arg);
                    });
            });
        })

        function jsFunc(){
            let data = {
                name: "lauf",
                age: 28
            }
            // js 调用 qt 端的函数,并传入参数(json序列化的数据)
            window.pyObj.py_func(JSON.stringify(data))
        }

        function getValue(){
            // js调用qt对象的属性,获取数据
            let data = window.pyObj.name;
            alert("获取的python数据:", data)
        }

    </script>
</body>
</html>

目录结构:
在这里插入图片描述
以Liver Server服务器启动,Qt端加载test.html页面。

 
2. PySide2 Qt端

from PySide2.QtWebEngineWidgets import QWebEnginePage, QWebEngineView, QWebEngineProfile
from PySide2.QtWebChannel import QWebChannel

# 定义一个类,继承QObject, 创建共享(Qt & js)的对象
class Lauf(QObject): # 必须继承QObject
    # 信号
    note = Signal(str)
    _name = "pypy"
    # 定义方法
    @Slot(str, result=str) # 必须装饰为槽函数 说明传值类型
    def py_func(self, data: str):
        print("py func run:", data)

    # 定义属性
    @Property(str)  # 必须装饰Property
    def name(self, *args):
        return self._name


class MyWindow(QWidget):
    def __init__(self, title="laufing"):
        super(MyWindow, self).__init__()
        # 窗口的尺寸及居中
        self.resize(800, 600)
        desk = QDesktopWidget().geometry()
        width, height = desk.width(), desk.height()
        self.move(width//2 - self.width()//2, height//2 - self.height()//2)

        # 窗口标题
        self.setWindowTitle(title)
        self.setWindowIcon(QIcon("./imgs/dog.jpg"))

        #
        self.set_ui()

    def set_ui(self):
        vb = QVBoxLayout(self)
        self.btn = QPushButton("点击")
        self.btn.clicked.connect(self.do_click)
        vb.addWidget(self.btn)
        self.web_view = QWebEngineView()
        vb.addWidget(self.web_view)

        # 创建共享对象
        self.lauf = Lauf()
        # 创建通道
        self.web_channel = QWebChannel()
        self.web_channel.registerObject("lauf", self.lauf)
        # 页面设置通道
        self.web_view.page().setWebChannel(self.web_channel)
        # 加载页面
        self.web_view.page().load(QUrl("http://127.0.0.1:5500/testWeb/test.html"))

    def do_click(self, *args):
        self.lauf.note.emit("qt端点击")


if __name__ == '__main__':
    import sys
    # 创建应用程序
    app = QApplication(sys.argv)

    win = MyWindow("测试可视化")
    win.show()

    # 进入消息循环
    sys.exit(app.exec_())

在这里插入图片描述
 

案例

  1. 前端 react + typescript
  2. Qt 端使用PySide2
    实现web js 与 Qt 之间的双向传值

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

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

相关文章

前端web3入门脚本三:一键完成与dex的交互,羊毛党必备

前言 该脚本用途&#xff1a;一键可以完成与dex的所有交互&#xff0c;包括2次swap&#xff0c;添加/移除流动性&#xff0c;以及farm和提取LP。一次运行可以有6条交易记录。 无论是个人单刷还是羊毛党批量地址刷交互都完美适配。当然反女巫方案不在这次文章的讨论范围内。 一、…

javascript中find(), filter(), some(), every(), map()等方法介绍

1、find() find() 用于找出第一个符合条件的数组成员。它的参数是一个回调函数&#xff0c;所有数组成员依次执行该回调函数&#xff0c;直到找出第一个返回值为true的成员&#xff0c;然后返回该成员。如果没有符合条件的成员&#xff0c;则返回undefined。 find()方法的回调…

利用Matab进行覆盖计算----战术计算

在 contour函数中添加如下代码 %------- 计算畅通区面积和占比例 --------% Spi*maxrange*maxrange/1e6; S0 nnz(isInRange)*reslons*reslats/1e6;isnn ~isnan(cdata); cdata0 cdata(isnn); S1numel(cdata0)*reslons*reslats/1e6;AS1/S0; % 畅通区所占比例; fprintf("…

CLion开发工具 | 06 - 使用CLion开发STM32(无需Cmake)

专栏介绍 文章目录 专栏介绍一、准备工作1. 工具准备2. 裸机工程准备二、使用CLion打开工程三、基于CLion写代码1. LED blink代码2. printf重定位代码四、编译工程1. 编译配置2. 选择编译目标3. 编译五、烧录1. OpenOCD基础知识(了解)2. 设置CLion路径3. 新建CLion配置文件4.…

面试总结,4年经验

小伙伴你好&#xff0c;我是田哥。 本文内容是一位星球朋友昨天面试遇到的问题&#xff0c;我把核心的问题整理出来了。 1&#xff1a;Java 层面的锁有用过吗&#xff1f;除了分布式锁以外 是的&#xff0c;Java中提供了多种锁机制来保证并发访问数据的安全性和一致性。常见的J…

分析GC日志解读

目录 GC分类 GC日志分类 GC日志结构剖析 透过日志看垃圾收集器 透过日志看GC原因 GC日志分析工具 GC分类 针对HotSpot VM的实现&#xff0c;它里面的GC按照回收区域又分为两大种类型&#xff1a;一种是部分收集&#xff08;Partial GC&#xff09;&#xff0c;一种是整堆…

VPN 虚拟专用网络隧道

1 什么是VPN VPN(全称&#xff1a;Virtual Private Network)虚拟专用网络&#xff0c;是依靠ISP和其他的NSP&#xff0c;在公共网络中建立专用的数据通信的网络技术&#xff0c;可以为企业之间或者个人与企业之间提供安全的数据传输隧道服务。在VPN中任意两点之间的链接并没有…

从零开始学习Linux运维,成为IT领域翘楚(二)

文章目录 &#x1f525;Linux系统目录结构&#x1f525;Linux用户和用户组&#x1f525;Linux用户管理 &#x1f525;Linux系统目录结构 文件系统组织结构 ⭐ /lib 系统开机所需要最基本的动态链接共享库&#xff0c;其作用类似于Windows里的DLL文件。 几乎所有的应用程序都需…

PACS系统源码,大型医院PACS源码集成三维重建

PACS系统为医院提供包括放射、超声、核医学、病理、内窥镜、心电图室在内的所有影像检查数字化的一体化解决方案。 它涵盖了传统PACS和RIS系统的所有功能&#xff0c;以构建全数字化影像科为目标&#xff0c;致力于实现对医院所有影像数据的统一管理、影像检查工作流的自动化&a…

POJ3704 括号匹配问题 递归方法

目录 题目 算法 完整代码 题目 参考 递归: https://blog.csdn.net/qq_45272251/article/details/103257953 利用了递归, 但思路稍复杂了 循环: https://blog.csdn.net/weixin_50340097/article/details/114579805 (看起来是递归其实是循环. 每次递归其实是循环内一次迭…

牛客网Python入门103题练习|【07--循环语句(2)】

⭐NP55 2的次方数 描述 在Python中&#xff0c; * 代表乘法运算&#xff0c; ** 代表次方运算。 请创建一个空列表my_list&#xff0c;使用for循环、range()函数和append()函数令列表my_list包含底数2的 [1, 10] 次方&#xff0c;再使用一个 for 循环将这些次方数都打印出来…

【Linux问题合集001】Linux中如何将用户添加到sudo组中的步骤

看教程的前提我的linux当前用户是zhou&#xff0c;看以下步骤时将zhou看做你的liunx当前用户就行了&#xff1a; 一、 以root用户登录到系统。 在Linux系统中&#xff0c;root用户是具有完全系统管理权限的超级用户。要以root用户身份登录到系统&#xff0c;您可>以使用以下…

继续打脸水货教程:关于可变对象与不可变对象

入门教程、案例源码、学习资料、读者群 请访问&#xff1a; python666.cn 大家好&#xff0c;欢迎来到 Crossin的编程教室 &#xff01; 今天这篇我要继续来打脸互联网上各种以讹传讹的水货教程。 前阵子我们聊了下Python中有关函数参数传递以及变量赋值的一些内容&#xff1a;…

LeetCode0014.最长公共前缀 Go语言AC笔记

时间复杂度&#xff1a;O(n) 解题思路 纵向扫描法。先扫描所有字符串的第一个字符&#xff0c;如果都相同就再次扫描所有字符串的第二个字符&#xff0c;直到某一字符串被扫描完或者出现了不相同的字符&#xff0c;此时就返回该字符串该字符的前缀。 为了确定所有字符是否相同…

【flask】三种路由和各自的比较配置文件所有的字母必须大写if __name__的作用核心对象循环引用的几种解决方式--难

三种路由 方法1&#xff1a;装饰器 python C#, java 都可以用这种方式 from flask import Flask app Flask(__name__)app.route(/hello) def hello():return Hello world!app.run(debugTrue)方法2: 注册路由 php python from flask import Flask app Flask(__name__)//app…

Java IO流第一章

Java IO流第一章 &#xff08;一&#xff09;简介 本文主要是从最基础的BIO式通信开始介绍到NIO , AIO&#xff0c;读者可以清晰的了解到阻塞、同步、异步的现象、概念和特征以及优缺点。 通信技术整体解决的问题 局域网内的通信要求。多系统间的底层消息传递机制。高并发下…

如何自制云平台,并实现远程访问控制?

除了阿里、腾讯各种云&#xff0c;计算机大神们都想自己搭建IoT云平台。今天小编跟大家分享一种用UbuntuEMQXNode-RED方式自制IoT云平台的方法&#xff0c;并实现无公网IP随时访问远程数据&#xff01; 第一步 Step1搭建EMQX服务器 1.搭建IoT平台需要一个服务器&#xff0c;这…

windows安装rocketmq

windows安装rocketmq 问题背景操作步骤Lyric&#xff1a; 请再给我 一个理由 问题背景 最近有使用rocketmq&#xff0c;为测试方便&#xff0c;在本地安装rocketmq 注意事项&#xff1a; 默认已安装java1.8&#xff0c;启动mq必须是1.8版本&#xff0c;我之前使用11版本&…

命令行 控制 易微联 wifi通断器

有个设备需要远程控制开关&#xff0c;最简单的方式就是通过一直在线运行的 Pi&#xff0c;进行命令行控制智能开关。 1、材料准备 找个最便宜的智能开关&#xff0c;话说易微联的做的真是便宜&#xff0c;销售量也很大。 这种 网上叫 Wifi通断器&#xff0c;或者智能开关&a…

使用ALLpairs完成正交表测试法练习题

该实验报告需要完成如下三个正交表测试法练习题 1、为了测试一个游戏软件的安装过程&#xff0c;需要考虑如下因素&#xff1a; (1) 操作系统: win2008、win7、win10、RedHat、Linux (2) 杀毒软件:瑞星、卡巴斯基、诺顿、江民、360 杀毒 (3) 数据库: oracle10g、SQLServer200…