PySide2 QWebEngine与Web js交互

文章目录

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

单向交互

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_())

PySide2 QWebEngine与Web js交互_第1张图片
只能单向传递数值、字符串,对象必须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>Documenttitle>
head>
<body>
    <button id="btn" onclick="jsFunc()">向python传值button>
    <button onclick="getValue()">获取python值button>

    
    <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>

目录结构:
PySide2 QWebEngine与Web js交互_第2张图片
以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_())

PySide2 QWebEngine与Web js交互_第3张图片
 

案例

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

你可能感兴趣的:(python,GUI,javascript,前端,Qt,PySide2,python)