python做界面的一个新思路(初始篇)
python做界面我首先想到的是pyqt5,但是笔者之前基本是用wpf做界面,再用其他的做界面都有点不畅快的感觉。直接用到了HTML + CSS + js。随着前端技术的快速发展,如VUE,AUI这类框架的兴起,做个炫酷的页面,远比后端做个界面要快捷方便的多。
但是HTML + CSS + js是运行在浏览器里的,这个系列文章就是要打破python和前端的壁垒,让它们携手打造桌面程序。
那么这个心思路就是,利用pyqt5的QtWebEngineWidgets和QtWebChannel来做媒介,
python完成后台功能,HTML + CSS + js完成全部的界面功能。
界面需要python功能时,js方便的调用python函数并获取返回值。这样各自完成擅长部分,想想都有点小激动呢。
那这样是否靠谱呢?
根据笔者的目前尝试,感觉还是很靠谱的:
1 运行不卡顿,相对于纯的pyqt我感觉这种界面运行起来更流畅。
2 QtWebEngineWidgets移植V8引擎,基本和谷歌的效果是一样的。Vue这样的框架也可以直接引用。
讲QtWebEngineWidgets的文章有很多,我学习这个时候看到网上的很多文章也和受益,但是,基本都是讲的一样的,没有深挖。
首先,QtWebEngineWidgets和QtWebChannel是可以实现双向交互的,但是,在应用的过程中我发现,python调用js会比较简单,有现成的语法可用,而且传输过程中有的数据的类型都不用转换。而且能获取到js的返回值。
而js调用python就复杂一点,传递类型也只能字符串和int(目前我测试的结果是这样),目前网上大多的例子就是基于共享属性这个概念,js是可以调用python函数,但是没法获取到返回值。
但是应用中你就会发现,基本都是js调用python,比如界面中的按钮点击后需要执行数据分析,然后将结果渲染在界面上。那么过程就是js调用py并获取返回值。
铺垫到此结束,接下来介绍js如何调用py,并获取返回值

""
js调用python并获取返回值.py
""
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtWebChannel import QWebChannel
from shared import Myshared
class MainWindow(QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle('js <-> py')
self.resize(330, 220)
self.layout = QVBoxLayout()
self.btn_test = QPushButton('test')
# self.btn_test.clicked.connect(self.test)
# 创建一个 QWebEngineView 对象
self.web = QWebEngineView()
file_path = QFileInfo("./test.html").absoluteFilePath()
self.web.load(QUrl(file_path))
# 把QWebView和button加载到layout布局中
self.layout.addWidget(self.web)
self.layout.addWidget(self.btn_test)
self.setLayout(self.layout)
self.channel = QWebChannel()
self.shared = Myshared()
self.set_channel()
def set_channel(self):
# 注册一个共享空间,取名"conn_shared",记住这个名字
# js中会用到
self.channel.registerObject("conn_shared", self.shared)
self.web.page().setWebChannel(self.channel)
def __del__(self):
'''
删除相关对象
'''
self.web.deleteLater()
# 让系统加快释放这部分内存,避免QWebEngineView崩溃
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
app.exit(app.exec_())
from PyQt5.QtWidgets import QWidget, QMessageBox
from PyQt5.QtCore import *
class Myshared(QWidget):
'''
共享类 shared.py
'''
@pyqtSlot(str, result=int)
def test_str_int(self, one_str):
print(one_str)
try:
r = int(one_str)
except Exception:
return -1
return r
@pyqtSlot(int, result=str)
def test_int_str(self, num):
return str(num + 111)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script language="javascript" src="./qwebchannel.js"></script>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>-->
<script src="./vue.js"></script>
</head>
<body>
<div id="app">
<button @click="on_test">{{a}}</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data:{
a : "js调用py,并获取返回值"
},
created: function () {
},
methods: {
on_test: function () {
// alert("123")
window.connection.test_str_int("3333", function(return_value){
alert(return_value);
});
window.connection.test_int_str(666, function(return_value){
alert(return_value);
});
}
}
})
document.addEventListener("DOMContentLoaded", function () {
new QWebChannel(qt.webChannelTransport, function(channel) {
window.connection = channel.objects.conn_shared;
});
// 当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发。
// 这样我们就新建一个QWebChannel对象(针对qwebchannel.js里的)。
// Web页面可以通过channel.objects属性访问所有已发布的对象,这里对象的id是“conn_shared”。
// 我们将其设置成JavaScript的全局变量:window.connection。
});
</script>
</body>
</html>
小结:
1 首先python中需要注册共享空间,js里才能访问到py。
2 js需要去获取channel.objects,他可以访问py中已发布的对象
3 js在调用py时,第二参数是一个回调,回调的参数结束py的返回值。
今天的内容就是这些,喜欢的可以点赞支持,如果点赞较多,关于这个知识点我将继续做一期有趣的内容。谢谢!
作者:宋桓公
出处:http://www.cnblogs.com/douzi2/
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现