0%

使用Electron & Python构建桌面GUI

使用Electron & Python 构建桌面GUI

需求整理

  • 本人项目核心代码使用Python语言,改写为其他语言需要较大时间投入
  • 需要构建一个桌面应用
  • Python相关的GUI库构建的桌面应用不美观灵活

可行性分析

  • 可行之处
    • Electron 可以较好地将Web应用做成桌面应用
    • Python通过flask,django等可以作为后端api和前端页面结合,制作Web应用
    • Web前端设计使用html5, css3, javascript以及相关框架,构建灵活且较为美观
    • 综上,可以解决需求
  • 问题点
    • Python作为后端的api,其如何与electron的前端通信

解决思路

  • 使用Python-Shell + win.loadURL解决
    • 在main.js中引用Python-Shell,定位到Python文件并运行,该文件可以启动flask或者django应用,即在本地’127.0.0.1:PORT’开放Web应用服务。
    • 使用win.loadURL(‘127.0.0.1:PORT’) 打开Web应用。

关键细节

  • Python-Shell 在打开Python脚本时的options配置

    • 需要配置Python.exe的位置和Scripts的位置
    • Scripts中需要预装所依赖的库
    • 打开脚本的路径,是相对于Scripts的位置
  • 建议:

    • 在开始项目时,Python使用虚拟环境,创建venv

      1
      $ python -m venv venv
    • 在虚拟环境中,配置所需要的库

    • 在main.js中,配置options,则根据venv的位置配置

样例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// main.js
const { app, BrowserWindow } = require("electron")

let options = {
mode: 'text',
pythonPath: 'E:/Anaconda/python.exe',
pythonOptions: ['-u'], // get print results in real-time
scriptPath: 'E:/Anaconda/Scripts/'
};

const {PythonShell} = require("python-shell")
PythonShell.run(
"../../example.py", options, function (err, results) {
if (err) throw err
console.log('test.py is running')
console.log('results', results)
})


// 创建窗口
function createWindow() {
let win = new BrowserWindow({
width: 800,
height: 600
})
// 加载 "templates/flask_welcome.html"
win.loadURL("http://127.0.0.1:8000")
}


// 启动
app.allowRendererProcessReuse = true;
app.on("ready", createWindow)

本实验在Python部分使用Django框架,此部分不展示。

下面的example.py文件,即是使用命令行打开dango应用而已。

1
2
3
4
# exmaple.py - use django
import os
path = 'manage.py' # path to your django manage.py file
os.system('python {} runserver'.format(path))
  • 打开后效果如下

  • 如上效果,和在浏览器中显示完全一致,即将electron看作chrome内核的浏览器使用,该种方法构建的桌面应用其实是一种变相的Web应用。

方案优缺点

  • 优点:
    • 省时、省力,充分发挥python和前端技术的优势
    • 应用展示美观
  • 缺点:
    • 启动慢,按照此方案,每次打开桌面应用,其都需要运行python脚本来开放web应用的端口,需要花费一点点时间。
    • 文件大,需要打包electron环境和python环境