Python + Flask + Electron 混合开发入门 (项目演示)
文章目录@[toc]写在前面概述背景正文1. 初始化项目2. 加入 python-shell3. 加入 flask4. python, flask, electron 混合与实现快速开始扩展阅读注意事项参考写在前面注: 如果您是第二次阅读本文, 推荐直接阅读 快速开始 章节以快速复现最终运行效果.本文所涉及文件已存放在网盘空间: https://www.jianguoyun.com/p/Dc...
写在前面
注: 如果您是第二次阅读本文, 推荐直接阅读 快速开始 章节以快速复现最终运行效果.
本文所涉及文件已存放在网盘空间: https://www.jianguoyun.com/p/DdlvwhwQ7t6sBxjJkcoB 欢迎下载使用.
概述
本文是基于一个 python 开发者的角度, 尝试使用 electron 来开发桌面应用.
请注意本文只是一个面向新手的文章. 内容涉及 如何让 electron 调用起 python 模块, 以及 python 的数据如何传递到 electron 界面展示出来.
背景
本文假设读者已具备以下能力:
- 有一定的 python 基础
- 有少量的 javascript 知识 (能够写出 hello world 的程度)
- 会用
npm init
初始化项目 - 完成过 electron 的 hello world 类项目的启动
本文假设读者已经做好以下准备:
- 安装 nodejs, npm, python 3
- 安装模块 (推荐安装在测试项目目录下):
- nodejs 模块: electron, python-shell
- python 模块: flask
- 安装模块 (推荐安装在测试项目目录下):
- 编辑器. vscode, pycharm, webstorm 都可以
- 创建本次测试项目的目录, 比如我的项目路径为 “D:/workspace/test_room/electron_with_python/”, 后面将简称为 “electron_with_python” 或者 “本项目”
正文
1. 初始化项目
通过 npm init
初始化项目. 得到的项目目录结构如下:
D:/workspace/test_room/electron_with_python/
node_modules/ # 这是 npm 在本项目的模块安装目录
venv/ # 这是 python 在本项目的虚拟环境 (包含编译器, 本项目安装的模块等)
index.html
main.js
package.json
然后在本项目中通过 npm install
和 pip install
来安装 electron, python-shell, flask 模块.
index.html, main.js, package.json 的源码见下面. 我尽量在保持易于阅读的基础上最简化 (注: 并非最终代码), 代码如下:
index.html
<h1>Welcome</h1>
<h3>This is a python-electron app.</h3>
main.js
// 导入模块
const { app, BrowserWindow } = require("electron")
// 创建窗口
function createWindow() {
let win = new BrowserWindow({
// 设置一个宽为800, 高为600的窗口
width: 800,
height: 600
})
// 加载本地的 index.html
win.loadFile("index.html")
}
// 启动
app.on("ready", createWindow)
package.json (注意 devDependencies
中要有 electron 和 python-shell 两个模块)
{
"name": "electron_with_python",
"version": "1.0.0",
"description": "Python + Flask + Electron 项目演示",
"main": "main.js",
"scripts": {
"start": "electron ."
},
"author": "Likianta",
"license": "ISC",
"devDependencies": {
"electron": "^4.1.3",
"python-shell": "^1.0.7"
}
}
在命令行 cd 到本项目路径, 输入 npm start
启动, 大家看到的效果应该和下图一样:
2. 加入 python-shell
python-shell 是一个 nodejs 模块, 所以可以在 main.js 中导入并使用.
python-shell 用于调用 python 写的 py 文件, 所以我们先在项目下新建一个 “hello.py” 文件:
# ./hello.py
# 里面就一句话
print("hello from python")
然后修改 main.js 文件:
const { app, BrowserWindow } = require("electron")
// 创建窗口
function createWindow() {
let win = new BrowserWindow({
width: 800,
height: 600
})
win.loadFile("index.html")
}
// 从 python-shell 导入一个 PythonShell 对象 (注意大小写)
const {PythonShell} = require("python-shell")
// PythonShell 主要有 run() 和 runString() 两个方法, 这里我们用 run()
// run() 第一个参数是要调用的 py 文件的路径
// 第二个参数是可选配置 (一般传 null)
// 第三个参数是回调函数
PythonShell.run(
"hello.py", null, function (err, results) {
if (err) throw err
console.log('hello.py finished')
console.log('results', results)
}
)
// 启动
app.on("ready", createWindow)
启动效果如下, 可以看到 main.js 中的两条 console.log()
都被触发成功:
[外链图片转存失败(img-BBICF1p5-1563031004213)(https://i.loli.net/2019/04/11/5cae1716b40c2.png)]
这意味着到了这里, 我们已经实现了 electron 调用 python 模块的功能.
3. 加入 flask
大家对 flask 可能比较陌生, 目前只需知道它是一个 python web 框架 (微服务) 就可以了.
既然是 web 框架, 就肯定有端口, 路由, html 渲染模板等东西.
在项目下新建一个 engine.py, 代码如下:
from flask import Flask, render_template
'''
导入的这两个模块, Flask 是主体类, render_template 是渲染模板.
'''
# 首先创建一个变量 app, 用于初始化 flask 启动核心
app = Flask(__name__)
'''
感兴趣的可以看一下它的源码, 当我们把 __name__ 传进去后, Flask 的实例化行为:
(flask 源码) app.py -> Flask.__init__()
(flask 源码) helpers.py -> _PackageBoundObject.__init__()
可以看到, Flask 会根据你传的 __name__ 定位到程序 (engine.py) 所在的根路径.
这个根路径的用处和 render_template 有关. 后面会讲.
'''
@app.route('/')
def homepage():
# 将本函数绑定到路由根地址, 这样我们访问主地址时, 就能看到这个页面
home = 'flask_welcome.html' # 还未创建, 接下来会写
return render_template(home)
if __name__ == "__main__":
# 启动, 启动后访问 http://127.0.0.1:5858 查看
app.run(host='127.0.0.1', port=5858)
再在项目下创建一个 “flask_welcome.html” 文件, 代码如下:
<h1>Welcome to Flask</h1>
<h3>This is a homepage rendered by flask.</h3>
现在我们尝试直接运行这个 py 文件看看效果:
不幸的是, 访问主页就报错了.
报错的原因在 pycharm 控制台可以看到, 显示 jinja2 没有找到模板文件:
(这也是我喜欢 python 的原因之一, 报错容易诊断, 定位错误源方便.)
jinja2 模块是 flask 默认使用的模板渲染引擎, 也就是 render_template(home)
这个函数, 之前我们还没有讲, 现在补充知识:
Flask 默认会在程序根目录下的 templates 文件夹寻找要渲染的模板文件, 所以这里传入的模板文件的路径应是相对于 templates 目录的.
因此解决方法有两种, 要么想办法让 Flask 类的 template_folder
成员不要用 “templates” 作为模板目录入口, 要么就创建一个 templates 目录, 把 “flask_welcome.html” 放到里面.
第一种方法用一个自定义类继承于 Flask, 就可以任你发挥了, 当然这里我只演示第二种方法.
现在我们确认一下目录结构应该如下面所示:
D:/workspace/test_room/electron_with_python/
node_modules/
templates/
flask_welcome.py
venv/
engine.py
hello.py
index.html
main.js
package.json
重新运行 engine.py, 在浏览器访问 http://127.0.0.1:5858/, 当如下图所示:
[外链图片转存失败(img-IS3WOL2g-1563031004214)(https://i.loli.net/2019/04/11/5cae171deed22.png)]
4. python, flask, electron 混合与实现
现在我们有了前三步的基础, 终于可以融会贯通了.
将 main.js 中的 “index.html” 改为 “templates/flask_welcome.html”, 把 “hello.py” 改为调用 “engine.py”, 来看看效果如何吧:
// main.js
const { app, BrowserWindow } = require("electron")
// 创建窗口
function createWindow() {
let win = new BrowserWindow({
width: 800,
height: 600
})
// 加载 "templates/flask_welcome.html"
win.loadFile("templates/flask_welcome.html")
}
// 使用 python-shell 调用 engine.py
const {PythonShell} = require("python-shell")
PythonShell.run(
"engine.py", null, function (err, results) {
if (err) throw err
console.log('engine.py is running')
console.log('results', results)
}
)
// 启动
app.on("ready", createWindow)
[外链图片转存失败(img-dgAbTzHF-1563031004215)(https://i.loli.net/2019/04/11/5cae1720e1f0c.gif)]
以上就是 python + flask + electron 的项目演示.
快速开始
注: 本节内容适合二次阅读的读者快速复习和复现.
-
初始化项目
-
创建项目: “D:/workspace/test_room/electron_with_python/”
-
项目目录结构:
D:/workspace/test_room/electron_with_python/ node_modules/ templates/ flask_welcome.py venv/ engine.py hello.py index.html main.js package.json
-
安装模块:
- npm install … : electron, python-shell
- pip install … : flask
-
-
创建代码文件: 请从此网盘链接下载: https://www.jianguoyun.com/p/DdlvwhwQ7t6sBxjJkcoB
下载此压缩包: “electron_with_python_20190411_000145.zip”
(PS: 为保持压缩包体积, node_modules 和 venv 里的内容我都清空了.) -
打开命令行, cd 到项目目录
-
输入
npm start
, 运行本项目 -
效果应与下图一致:
扩展阅读
TODO
注意事项
- electron 的调试器端口不可以和 flask 相同, 否则会报错
参考
- Using Electron with Flask and python-shell | Techiediaries https://www.techiediaries.com/flask-electron-tutorial/
- [李辉] Flask Web 开发实战 - 入门, 进阶与原理解析
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)