python做界面的一个新思路(初始篇)

news/2024/7/19 14:57:14 标签: js, python, javascript, vue, java

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,并获取返回值

工程目录结构
python">""
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_())
python">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>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.niftyadmin.cn/n/1734864.html

相关文章

xadmin卡顿延迟的原因

最近突然发现xadmin卡的不行。最后发现居然是主题导致的&#xff0c;切换成默认主题就不卡了。 图片.png感谢下面这位同学的提醒~~~~ 图片.png

Vagrant 创建的虚拟机 如何用xshell登陆(初步记录)

vbox 图片.png图片.pngxshell 图片.png图片.png图片.png图片.png

django 显示media图片的几个关键点

1 将url中的路径关联到服务器本地图片路径 url(r^media/(?P<path>.*)$, serve, {"document_root": MEDIA_ROOT}), 2 全局上下文注册&#xff0c;确保 def media(request): """ Add media-related context variables to the context. "&qu…

“机缘巧合” 我学了一下java

作为一个工作了8年之久的程序员&#xff0c;我学过很多的语言&#xff0c; C/C verilog C# python nodejs/js , 但是就是没有去学一下java。 巧的是&#xff0c;我所在的项目组&#xff0c;几乎清一色的java。在这种环境下&#xff0c;我几乎一个人用着python维护者采集侧的代码…

URL里莫名出现%20问题,导致图片访问不到

<img width"90" height"90" style"border-radius:50px;" src"{% static img/song.jpg %}"> 这是写链接的时候多个一个空格导致的。 这个错误&#xff0c;用django调试的时候&#xff0c;图片访问不会有问题&#xff0c;但是…

小程序django后台开发https支持记录

后台我采用的是django django 本身针对小程序&#xff0c;不需要特殊的配置。 但是nginx需要对https进行支持。 首先需要ssl证书&#xff0c;阿里云提供免费的ssl&#xff0c;可以使用。 image.png点击下载&#xff0c;选择nginx的方式&#xff0c;会下载两个文件&#xff0c;一…

micro usb接口正负极_ORICO这个U盘有三种接口,堪称安卓设备用户必备利器

虽然现如今移动硬盘已经成为了商务人士以及学生用户们在选购移动存储设备时的首选&#xff0c;但拥有出色便携性优势的U盘依旧是生活与工作中必备的配件。如果你是安卓手机、安卓平板用户&#xff0c;并且正打算入手一款U盘的话&#xff0c;相信ORICO推出的这款三接口U盘(ORICO…