前言
使用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)
完结
网友评论