美文网首页我的Python自学之路
Python QWebEngineView Python与 Ja

Python QWebEngineView Python与 Ja

作者: 戎码虫 | 来源:发表于2020-06-19 00:47 被阅读0次
人生信仰

前言

使用Qt5的QWebEngineView加载Html时,需要客户端与网页进行交互,看了官网和搜了很多博客都没搜到相关的信息,只有单方向交互;这里把双向交互相关代码做个总结,希望可以帮助需要的人。

实现

这里介绍Python改变Js值,Python调用Js方法并返回回调,Js调用Python方法并返回回调。

web.html
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
        <title>Python与Js通信</title>
        <script src="qwebchannel.js"></script>
        <style>
        html, body {
            margin: 0;
            padding: 0;
            height: 100%;
            width: 100%;
        }

        .input-card {
            padding: 2rem;
        }

        .input-item{
           display: flex;
           justify-content: center;
        }

        .btn{
            width: 50%;
            margin-top: 1rem;
        }

        .btn:last-child{
            margin-left: 1rem;
        }

    </style>
    </head>
    <body>
        <div class="input-card">
            <h4>控制按钮</h4>
            <div class="input-item">
                <input type="button" class="btn" value="调用py改变js的变量值" onclick="changeJsValueByPy()" />
                <input type="button" class="btn" value="展示js变量值" onclick="showValue()" />
            </div>
            <div class="input-item">
                <input type="button" class="btn" value="js调用py,接收返回" onclick="jsCallPy()" />
                <input type="button" class="btn" value="py调用js,接收返回" onclick="callPy2JsByJs()" />
            </div>
        </div>

        <script>
            document.addEventListener("DOMContentLoaded", function() {
                //把对象赋值到JS中
                new QWebChannel(qt.webChannelTransport, function(channel) {
                    window.pyjs = channel.objects.Bridge;
                });
            });

            //调用python给js变量赋值 py2js
            function changeJsValueByPy() {
                pyjs.changeJsValueByPy();
            }

            //等待接收python传来的数据 py2js
            var defaulitValue = null;
            //展示值
            function showValue() {
                alert(defaulitValue);
            }

            //向python传值,并接收返回
            function jsCallPy() {
                pyjs.jsCallpy('js呼叫py,收到请回答', function(result) {
                    alert("来自py回复:" +result);
                });
            }

            //调用python方法,给js传值
            function callPy2JsByJs() {
                pyjs.callPy2JsByJs1();
            }

            //py调用js方法并返回值
            function pyCalljs(msg) {
                alert("来自py消息:" + msg);
                return 'py,js收到'
            }
        </script>
    </body>
</html>
运行截图
html效果
webview.py
# -*- coding:utf-8 -*-
import os
import sys
from PyQt5.QtWidgets import QApplication, QMessageBox
from PyQt5.QtCore import QObject, pyqtSlot, QUrl
from PyQt5.QtWebChannel import QWebChannel
from PyQt5.QtWebEngineWidgets import QWebEngineView


class BridgeClass(QObject):
    """
       一个槽函数供js调用(内部最终将js的调用转化为了信号),
       一个信号供js绑定,
       这个一个交互对象最基本的组成部分.
    """

    # pyqtSlot,网络上大多将其翻译为槽。作用是接收网页发起的信号
    @pyqtSlot()
    def changeJsValueByPy(self):
        web_view.page().runJavaScript('defaulitValue="value from python"')

    # 注意pyqtSlot用于把该函数暴露给js可以调用
    @pyqtSlot()
    def callPy2JsByJs1(self):
        print('中间代理')
        self.pyCalljs('py呼叫js,收到请回答')

    def pyCalljs(self, msg):
        web_view.page().runJavaScript("pyCalljs('%s')" % msg, self.js_callback)
        print(msg)  # 查看参数

    # 回调函数,接收js返回的值
    def js_callback(self, result):
        QMessageBox.information(None, "提示", "来自js回复:{}".format(result))
        print(result)


    # 注意pyqtSlot用于把该函数暴露给js可以调用 result=str返回的值string
    @pyqtSlot(str, result=str)
    def jsCallpy(self, text):
        QMessageBox.information(None, "提示", "来自js消息:{}".format(text))
        return 'js,py收到消息'


if __name__ == '__main__':
    app = QApplication(sys.argv)
    # 新增一个浏览器引擎
    web_view = QWebEngineView()
    # 增加一个通信中需要用到的频道
    myChannel = QWebChannel()
    # 用于通信的对象
    bridgeClass = BridgeClass()
    # 注册,testObject是自己起的名字
    myChannel.registerObject('Bridge', bridgeClass)
    # 在浏览器中设置该频道
    web_view.page().setWebChannel(myChannel)

    # 获取当前文件夹位置
    path_url = os.path.abspath('.')
    url_string = 'file://' + path_url + '/web.html'
    web_view.load(QUrl(url_string))
    web_view.show()
    sys.exit(app.exec_())
调用Js截图
js调py py弹框 js弹框

其它几个调用类似

注意关键几个点

1、 Html 引用qwebchannel.js文件,qwebchannel时Js与Python之间的通信桥梁;

<script src="qwebchannel.js"></script>

2、BridgeClass继承QObject类,将对象注册到频道中去;

myChannel.registerObject('Bridge', bridgeClass),

3、在Html中将Python的对象注册到Js中;

//把对象赋值到JS中
new QWebChannel(qt.webChannelTransport, function(channel) {
        window.pyjs = channel.objects.Bridge;
 });

4、@pyqtSlot(),槽的作用是接收网页发起的信号的注解;
5、Js传递值给Python,需要写明数据类型 @pyqtSlot(str, result=str),第一个参数表示Js传递过来数据类型,result=第二个参数表示Python传给Js值的数据类型;
6、Python调用Js方法,使用QWebEngineView中runJavaScript执行Js中的方法并传参,第二个参数可以注册Js返回数据监听方法;

 web_view.page().runJavaScript("pyCalljs('%s')" % msg, self.js_callback)
完结

相关文章

网友评论

    本文标题:Python QWebEngineView Python与 Ja

    本文链接:https://www.haomeiwen.com/subject/mpqmxktx.html