之前分别用过了eel
, pywebview
进行桌面应用开发, 但是都有不太理想的地方, eel
没有对flask的原生支持, 而pywebview
虽然可以直接将flask的实例对象进行传递, 用起来也挺方便, 不过在调用浏览器引擎方面有点难受, 要么用cef
, 就得带进去一大堆依赖, 如果用pyinstaller
打包后还会出现各种跑不起来的坑, 要么就是用IE
内核, 那简直要了亲命的, 还不能指定调用外部的Chrome浏览器进行渲染, 很是尴尬…要是能有一个轮子结合eel
和pywebview
的优点, 可以直接用flask+Chrome跑的话那就完美了, 嘿嘿~还真让我给翻出来了: flaskwebgui
, 下面开始实例记录一个小demo
https://github.com/ClimenteA/flaskwebgui
是个19年开始做的项目, 更新还是蛮频繁的, 感谢作者ClimenteA
pip直接安装就行
pip install flaskwebgui
用auto-py-to-exe
打包后扔到纯净的Win7虚拟机中进行测试, 除了需要单独安装一下Chrome以外, 不需要任何运行环境即可直接跑起来.
就是正常的一个flask应用的结构, 这里我用了CDN, 没有加static
文件夹
.
├── main.py # 入口程序
└── templates
└── index.html # 页面模板
from flask import Flask, render_template
from flaskwebgui import FlaskUI
# 正常实例化flask对象
app = Flask(__name__)
# 将app对象传入FlaskUI的构造函数中, 并设置要打开的窗口尺寸
ui = FlaskUI(app, width=800, height=600)
@app.route('/')
def index():
return render_template('index.html')
if __name__ == '__main__':
# 注意这里调用的是ui的run
ui.run()
纯前端的代码, 其实没啥好贴的了, 从layui文档里面抄了一段后台模板测试下. 主要就是一个需要注意的地方, 记得设置页面的语言<html lang="zh">
, 否则调用Chrome的时候会提示是否需要进行翻译, 比较讨厌.
<!DOCTYPE html>
<html lang="zh"> <!--注意设置语言, 否则调用Chrome打开会出现是否翻译的提示-->
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flaskwebgui演示程序</title> <!--这里将会是打开的Chrome标题-->
</head>
<body>
<div class="layui-layout layui-layout-admin">
中间省略了, 没啥参考价值
</div>
</body>
</html>
这里还是用auto-py-to-exe
, 比手工配置pyinstaller
更方便, ps: 这货是eel写的
pip install auto-py-to-exe
auto-py-to-exe
注意把templates
文件夹添加到打包的选项里就行
默认参数打包后的文件夹大小22MB多点
开UPX压缩试试:
直接干掉一半大小, 变成10MB了, 哇哈哈哈哈
然而…启动upx压缩后的程序报错:
本着这种问题我肯定不会是第一个发现的原则, 果然在stackoverflow上找到了病友:
https://stackoverflow.com/questions/38811966/error-when-creating-executable-file-with-pyinstaller
upx压缩的时候把VCRUNTIME140.dll
给干残了, 单独设置一下不压缩这个文件, 注意上面设置的--upx-dir
参数不变, 额外添加手动参数: --upx-exclude=vcruntime140.dll
, 这样完整的命令:
pyinstaller --noconfirm --onedir --windowed --upx-dir "D:/tools/upx-3.96-win64" --add-data "C:/Users/Lian/Desktop/flaskgui/templates;templates/" --upx-exclude=vcruntime140.dll "C:/Users/Lian/Desktop/flaskgui/main.py"
再打包, 文件夹就大了0.1MB而已, 这次运行正常! 整个文件夹再打个zip, 只有9MB了, 好吧, 承认是我强迫症犯了…
进行应用分发的时候可以直接把这个压缩包+Chrome的standalone安装包扔给用户, 先装Chrome, 然后再解压执行main.exe
就可以了.
这么一来的话, Chrome居然变成了运行环境RUMTIME, 不过相对于之前用.Net Framework做Winform类的桌面应用而言, 这种方式算是完美结合了WEB技术出炫酷的UI界面+Python各种轮子快速实现业务逻辑的优势, 当然缺点嘛, 可能就是第一次启动程序调用Chrome的时候会有点略慢, 不过关掉后再启动就挺快了.
这貌似是当前版本存在的bug, 就是在关闭浏览器之后, 后台的flask进程并没有自动退出, 看了下GitHub上的issue, 果然我又不是第一个哈哈哈哈:
https://github.com/ClimenteA/flaskwebgui/issues/58
根据热心网友提出的方案, 改一下flaskwebgui.py
源代码313行的while True:
开始的内容, 加一层try except
来捕获异常强制退出flask就行了, 修改后的这部分代码:
while True:
try: # 增加的内容
gui_running = psutil.Process(
self.BROWSER_PROCESS.pid).is_running()
gui_memory_usage = psutil.Process(
self.BROWSER_PROCESS.pid).memory_percent()
if (
gui_running == False
or
gui_memory_usage == 0
):
break
time.sleep(5)
except Exception as e: # 增加的内容
logging.info('Forced Shutdown Browser Closed')
break
if isfunction(self.on_exit):
logging.info(f"Executing {self.on_exit.__name__} function...")
self.on_exit()
else:
logging.info("No 'on_exit' function provided.")
logging.info("Closing connections...")
FlaskUI.kill_pids_by_ports(self.port)
估计后续的更新可能会修复这个bug吧, 可以跟进一下这个项目了, 真的很不错!
又尝试了一下在auto-py-to-exe
中打包成单个可执行文件, 对于额外引入的templates
文件夹, 需要在主程序中修改一下访问路径的逻辑, 不能直接用默认的, 看代码吧:
import os
import sys
from flask import Flask, render_template
from flaskwebgui import FlaskUI
# 使用pyinstaller打包成单文件需要处理路径问题
app_path = ''
if hasattr(sys, '_MEIPASS'): # 如果是单个EXE文件执行的时候sys中会存在这个_MEIPASS变量作为当前的工作根路径
app_path = os.path.join(sys._MEIPASS)
# 拼接一下获得模板文件夹所在的绝对路径, 这样写不会影响打包前对源代码的调试
template_folder = os.path.join(app_path, 'templates')
# 实例化Flask对象的时候就得指定一下template_folder的位置了, static文件夹同理.
app = Flask(__name__, template_folder=template_folder)
附上打包成单个EXE文件后的运行效果, 只有9MB哦! 估计是用CDN的原因, 启动的前两秒空白等待了一会儿, 还是把静态资源打包到程序里面比较好.
原网址: 访问
创建于: 2024-12-17 12:18:10
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论