首页 > Python资料 博客日记

用Python开发桌面端软件:pywebview (框架) + Python (后端) + vue (前端) + pyinstaller (打包)

2024-10-03 13:00:05Python资料围观35

Python资料网推荐用Python开发桌面端软件:pywebview (框架) + Python (后端) + vue (前端) + pyinstaller (打包)这篇文章给大家,欢迎收藏Python资料网享受知识的乐趣

遇到相关问题欢迎邮件交流(1554610593@qq.com),或评论区留言(不过回应会很慢)。

单兵简单开发,Python几乎可以满足所有需求。那么,2024年了,想写一个简单的windows桌面端软件,点击exe打开运行的那种,并且所有后端业务都用Python编写,应该怎么做?请看这个笔者用Python开发的用于微信群聊拍卖统价的桌面端软件:

效果是很好的,既美观又好用,并且所有的业务代码都是用Python写的(诸如管理数据库、读取和写入excel表格、计算竞价)。

用Python编写桌面GUI,可能最先想到的就是pyQt、Tkinter这种,但它们不是太臃肿,就是学习曲线高,而且功能局限,开发出的前端并不美观。

在开发前端方面,没有比Web网页开发更灵活强大的了,何况还有现成的web框架和海量的组件可以直接使用。但是,网页毕竟要在浏览器中打开,并不算一个封装好的桌面端软件。使用Electron倒是可以把网页浏览器伪装成一个桌面软件,但抛开学习成本不说,软件的业务层(也就是后端)是用node.js编写的,远没有Python灵活强大。

那么,2024年了,能不能用Web网页做前端,Python写后端,然后封装成一个桌面软件的样子呢?这样一来,只需要会Python和一点前端js框架,就可以写出一个美观又功能强大的桌面软件了。这就是笔者想推荐一种技术方案:pywebview (框架) + Python (后端) + vue (前端) + pyinstaller (打包)。目前也已经有大佬想到了这一套方案,并开发出了一个框架 PPX,方便大家直接在此基础上开发。笔者用这套方案很方便地开发出了桌面端软件。

  • pywebview是一个Python库,可以用pip直接安装,几行Python代码就能把一个网页伪装成桌面窗口打开。原理是调用了系统的浏览器内核,打开了一个浏览器窗口来渲染网页。最神奇的是,它允许前端js中直接调用后端用Python编写的函数。具体的实现方式是在Python中编写一个api类,业务代码写成它的成员函数xxx,pywebview在创建窗口时接收这个api类和前端网页作为参数,然后你就可以在前端js代码中直接用pywebview.api.xxx去调用Python函数。
  • vue是最流行的前端Web框架之一,它的优点是上手简单,template和原生html很像,js的编写简单(尤其是新版本的vue支持组合式API写法),同时还有Element Plus等配套的UI组件库可以使用。
  • Python实现后端业务有诸多好处,最重要的是Python有丰富的库可以直接调用,功能非常强大。Python也有Django等前后端开发框架,但是这种传统的web开发模式的前后端是通过网址api的方式通信的。而在pywebview下,前端可以直接调用后端Python函数,前后端的通信pywebview都帮你封装好了,开发者可以专注于用Python进行业务功能实现。
  • 项目写好后,将vue项目打包成一个小巧的文件夹(包含html和js等),pywebview中的前端指向该文件夹就可以将其渲染出来。由于其它部分都是用Python编写的,可以用pyinstaller将其打包成一个exe文件。

这套方案在框架 PPX 中已经帮你跑通了,感兴趣的读者可以去仔细研究一下这个框架的源码,相信也能自己用Python捣鼓出一个桌面端软件。但其中肯定也会遇到一些坑,诸如笔者遇到过的这些:

  • 项目打包后,窗口打开白屏。在开发阶段vue网页都打开正常,但最后用vite生成了html和js,并打包好了exe文件,打开就白屏了。这个时候最好在pywebview的参数里设置保留控制台,这样打开窗口后可以按F12查看控制台(没错,就是chrome浏览器的那个控制台),看看是什么报错。如果也没什么报错,可能就是vite打包的问题,笔者就遇到了vite引起的和pywebview不对付的情况。所以还是推荐用之前的Vue CLI脚手架来搭建和生成vue项目吧,vite确实有一些坑。
  • 打包时间太长,生成的exe过大。pyinstaller打包也很有讲究,如果不是在新建的Python环境中打包,很可能把很多无关的Python库也打包进来。建议感兴趣的读者去研究一下 PPX 的作者是怎么处理的,不懂的也可以评论区留言。
  • 关于在js中调用pywebview的Python函数,还有一些讲究的:
    • pywebview会自动将js的数据类型和Python的数据类型进行转换。具体的,函数返回的Python对象都将被jsonify,就是转换成json格式发给前端,所以只有list、dict等这类基础类型可以在前后端之间传递。其它类型要想办法转换成可以变成json的再传递。
    • 在js调用后端api函数 (比如xxx),最好封装一下,处理好错误信息:
      try {
          pywebview.api.xxx(params).then((res) => {
          	// ...处理后端返回的结果res...
              console.log('成功执行');
          }).catch((err) => {
          	// 如果Python执行抛出异常,会在这里处理
              console.log(err.message)
          })
      } catch (err) {
      	// 如果js函数执行出错(如不存在xxx函数,或pywebview还没加载好)
      	// 会在这里处理
          console.log(err.message)
      }
      
    • 要想在前端组件初始化时就调用后端函数(比如拉取一些初始化数据),要小心pywebview还没加载好,前端还找不到后端api。可以编写下面这个钩子,用runAfterPywebview(fn)就可以确保fn在pywebview加载后再执行:
      // 用于在检查pywebview加载完成后执行某个函数, timeInterval为检查间隔,timeLimit为检查超时时间
      export function runAfterPywebview(fn, timeInterval = 100, timeLimit = 3000) {
          let time2now = 0
          let timer = setInterval(() => {
              time2now += timeInterval
              // 如果已经超时pywebview还没加载好,报错。
              if (time2now > timeLimit) {
                  console.log({
                      message: 'pywebview加载超时',
                      showClose: true,
                  })
                  clearInterval(timer)
                  timer = null
                  return
              }
              // 没有超时,只有当pywebview加载好才执行fn。
              if (window.pywebview != undefined) {
                  fn()
                  clearInterval(timer)
                  timer = null
                  return
              }
          }, timeInterval)
      }
      

此外,还可能遇到其它问题,欢迎与笔者交流。


版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐