1 Star 2 Fork 0

guanfuchang/python-electron-app

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
ISC
# electron + flask server 开发/打包项目示例 ## 开发环境 **python3.6.8** **node v12.22.5** **win7** ## 初始化项目 ``` mkdir python-electron-app cd python-electron-app npm init -y ``` 初始化后,在项目python-electron-app中,生成的pacakge.json大致如下 ```json { "name": "python-electron-app", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" } ``` ## 开发 flask server * (建议) 创建python虚拟环境进行管理 ```cmd python -m venv venv ``` ```cmd venv\Scripts\activate.bat ``` * 安装本相关python模块 ```cmd pip install flask==2.0.1 pip install flask-cors==3.0.10 pip install simplecalculator==0.0.4 pip install dataclasses==0.6 pip install pyinstaller==4.5.1 ``` * 在项目根目录下,创建py文件夹,后续在py文件夹下进行python代码开发 * 创建flask app.py 内容如下: ```python from calculator.simple import SimpleCalculator from flask import Flask, render_template from flask_cors import cross_origin app = Flask(__name__) def calcOp(text): """based on the input text, return the operation result""" try: c = SimpleCalculator() c.run(text) return c.log[-1] except Exception as e: print(e) return 0.0 @app.route('/') def homepage(): home = 'flask_welcome.html' return render_template(home) @app.route("/<input>") @cross_origin() def calc(input): return calcOp(input) if __name__ == "__main__": app.run(host='127.0.0.1', port=5001, use_reloader=False) # 注意,如果没有指定use_reloader=False,后续将其打包成exe后,运行exe会产生两个进程,在electron窗口关闭时kill掉进程时,会有一个守护进程无法kill掉 ``` * 创建flask template 如下: templates/flask_welcome.html ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>Welcome to Flask</h1> <h3>This is a homepage rendered by flask.</h3> </body> </html> ``` * 测试 flask server 运行情况 ```cmd python py/app.py ``` 访问 127.0.0.1:5001 后,正常情况会返回flask_welcome.html中的内容; 访问 127.0.0.1:5001/1 + 1 ,正常情况会返回calc视图的响应内容:result:2.0 ## 安装局部electron `cnpm install --save-dev electron@14.0.1 -S` 本版本安装的electron版本为“14.0.1” ## 创建electron主入口 主入口由package.json 中的main指定,如本项目,主入口为`index.js` * 在项目根目录下创建index.js 如下 ```js // 引入nodejs模块 const {app, BrowserWindow} = require('electron'); const path = require('path'); // 创建窗口函数 function createWindow() { win = new BrowserWindow({ // 设置窗口option width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation: false, // 注意如果没有该选项,在renderer.js 中 require is not defined enableRemoteModule: true } }); win.loadFile('index.html');// 窗口加载本地html win.webContents.openDevTools(); // 打开开发者工具调试选项 } // 启动flask server,通过python-shell 调用python脚本(开发调试阶段) function startServer_PY() { var {PythonShell} = require('python-shell'); let options = { mode: 'text', pythonPath: 'venv/Scripts/python' }; PythonShell.run('./py/app.py', options, function (err, results) { if (err) throw err; // results is an array consisting of messages collected during execution console.log('response: ', results); }); } // 初始化函数 function initApp() { startServer_PY(); createWindow(); } // electron ready 事件触发 app.on('ready', initApp); // electron 窗口关闭事件触发 app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } }); ``` * 安装python-shell 模块 `cnpm install python-shell -S` * 在项目根目录下创建index.html 如下 ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Calling Python from Electron!</title> <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self';connect-src *"> </head> <body> <h1>Simple Python Calculator!</h1> <p>Input something like <code>1 + 1</code>.</p> <input id="input" value="1 + 1"></input> <input id="btn" type="button" value="Send to Python!"></input> </br> Got <span id="result"></span> <a href="http://127.0.0.1:5001/">go flask template</a> <script src="./renderer.js"></script> </body> </html> ``` * 创建渲染进程renderer.js 如下 ```js let input = document.querySelector('#input'); let result = document.querySelector('#result'); let btn = document.querySelector('#btn'); function onclick() { // 发送http请求 fetch(`http://127.0.0.1:5001/${input.value}`).then((data) => { return data.text(); }).then((text) => { console.log("data: ", text); result.textContent = text; }).catch(e => { console.log(e); }) } // 添加按钮点击事件 btn.addEventListener('click', () => { onclick(); }); ``` ## 运行electron 在package.json 的scripts中添加运行命令如下 `"start": "electron ."` 在项目根目录下,执行命令运行 `npm run start` 运行后,正确情况是打开electron窗口: 点击按钮"Send to Python"后,会正确发送请求到flask中并获得响应; 点击链接“go flask template” 则会跳转到flask_welcome.html中。 ## flask 打包成exe * 在package.json 中的scripts 里面添加python打包脚本 ` "build-python": "pyinstaller -D -p ./venv/Lib/site-packages py/app.py --add-data=py/templates;templates --distpath ./pydist",` -p 指定依赖包位置,如果没有指定,打包后会缺少响应的依赖模块 --add-data 指定外部资源位置,如果没有指定,运行后会找不到flask template 资源 * 运行打包脚本 `npm run build-python` 打包完成后,会生成可执行文件 pydist/app/app.exe,可运行该exe检查flask是否正确运行 ## 调整electron index.js 调整前,是使用python-shell调用app.py 脚本来启动flask。当flask打包成exe后,需调整启动flask位置的命令 调整后如下 ```js // 引入nodejs模块 const {app, BrowserWindow} = require('electron'); const path = require('path'); // 创建窗口函数 function createWindow() { win = new BrowserWindow({ // 设置窗口option width: 800, height: 600, webPreferences: { nodeIntegration: true, contextIsolation: false, // 注意如果没有该选项,在renderer.js 中 require is not defined enableRemoteModule: true } }); win.loadFile('index.html');// 窗口加载本地html win.webContents.openDevTools(); // 打开开发者工具调试选项 } // 启动flask server,通过python-shell 调用python脚本(开发调试阶段) function startServer_PY() { var {PythonShell} = require('python-shell'); let options = { mode: 'text', pythonPath: 'venv/Scripts/python' }; PythonShell.run('./py/app.py', options, function (err, results) { if (err) throw err; // results is an array consisting of messages collected during execution console.log('response: ', results); }); } // 启动flask server,通过子进程执行已经将python项目打包好的exe文件(打包阶段) function startServer_EXE() { let script = path.join(__dirname, 'pydist', 'app', 'app.exe') pyProc = require('child_process').execFile(script) if (pyProc != null) { console.log('flask server start success') } } // 停止flask server 函数 function stopServer() { pyProc.kill() console.log('kill flask server success') pyProc = null } // 初始化函数 function initApp() { startServer_EXE(); createWindow(); } // electron ready 事件触发 app.on('ready', initApp); // electron 窗口关闭事件触发 app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit() } stopServer() }); ``` * 重新运行electron进行调试 `npm run start` ## electron 打包 * 安装electron打包模块 `cnpm install --save-dev electron-packager@15.4.0 -S` * 在package.json 的scripts中添加打包命令 `"pack-app": "electron-packager . --overwrite --ignore=py$ --arch=x64 --download.mirrorOptions.mirror=https://npm.taobao.org/mirrors/electron/"` 注意,如果没有指定--download.mirrorOptions.mirror,下载对应系统的electron-xxx.zip 包会耗时非常长!!! * 运行electron 打包命令 `npm run pack-app` ## electron-winstaller 打包成一个可执行exe ** (1)安装electron-winstaller、electron-squirrel-startup `npm install electron-winstaller@5.0.0 --save-dev` `npm install electron-squirrel-startup --save` ** (2)在根目录下新建打包需要的一个build.js文件 ```js var electronInstaller = require('electron-winstaller'); var path = require("path"); resultPromise = electronInstaller.createWindowsInstaller({ appDirectory: path.join('./python-electron-app-win32-x64'), //入口,electron-package生成的文件目录 outputDirectory: path.join('./installer64'), //出口,electron-winstaller生成的文件目录 authors: 'Milton', exe: "python-electron-app.exe", //在appDirectory 目录下已生成的exe setupIcon: "./icon.ico",//安装图标,必须本地 // iconUrl: 'http://pm72qibzx.bkt.clouddn.com/icon.ico',//程序图标,必须url noMsi: true, setupExe:'python-electron-app.exe', title:'python-electron-app', description: "python-electron-app" }); resultPromise.then(() => console.log("It worked!"), (e) => console.log(`No dice: ${e.message}`)); ``` ** (3) 执行打包命令 `node build.js` 打包完成后,会在installer64目录下生成一个可执行exe文件。 ## electron-builder 打包成可安装文件 ** (1) 安装electron-builder `npm install electron-builder@22.9.1 --save-dev` ** (2) 在package.json 中添加 build配置 ```js "build": { "appId": "com.guanfc.app", "productName": "demo", "win": { "icon": "chrome.png", "target": [ "nsis" ], "arch": [ "ia32" ] }, "nsis": { "oneClick": false, "perMachine": true, "allowToChangeInstallationDirectory": true, "createDesktopShortcut": true, "createStartMenuShortcut": true } } ``` ** (3) 在package.json 的Scripts中添加打包命令 `"build": "electron-builder"` 执行打包命令 `npm run build` ,打包过程要下载资源,大概率要翻墙才可以成功,OMG!

简介

flask+electron 开发/打包demo 展开 收起
JavaScript 等 3 种语言
ISC
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/guanfuchang/python-electron-app.git
git@gitee.com:guanfuchang/python-electron-app.git
guanfuchang
python-electron-app
python-electron-app
master

搜索帮助