首页 > 解决方案 > 编译后 Tkinter 和 Flask 集成不起作用

问题描述

我有一个专为 Flask 设计的小型 Web 应用程序,旨在本地运行。我使用 Flask 是因为我更喜欢在 GUI 上使用 Web 浏览器,即使这是一个本地应用程序。我想与我的同事分享这个应用程序,所以我使用 pyinstaller 创建了一个可执行文件。这完美地工作,但需要终止进程来停止 Flask。我希望能更优雅地做到这一点,我发现了这一点:

与 Flask 应用程序同时运行 GUI

这听起来与我正在尝试做的完全一样。经过一番试验,我终于让一切正常了。启动应用程序会打开一个 tkinter 窗口。用户可以使用显示的按钮启动或停止 Flask 应用程序。启动 Flask 应用程序会将默认 Web 浏览器打开到正确的页面。Flask 应用程序作为一个新进程启动,tkinter 窗口是父/守护进程。关闭 tkinter 窗口或按下停止按钮会终止 Flask 服务器。在我的开发环境中一切都按预期工作,但当我使用 pyinstaller 为 Windows 编译它时却没有。

作为 .exe 文件,tkinter 窗口打开,但 Flask 服务器未启动。按下“开始”按钮时,网页打开,但显示标准的“未找到站点”消息。然后,我的 tkinter 窗口会自我复制,因此显示了两个窗口。如果我编辑我的代码以立即启动 Flask 服务器并绕过打开 tkinter 窗口,一切都会再次运行。

下面是我的应用程序的布局:

|   run.py
+---my_flask_app
|   |   forms.py
|   |   routes.py
|   |   __init__.py
|   |   
|   +---static
|   |   +---css
|   |   +---img
|   |   \---js
|   |           
|   +---templates

除非需要更多,否则我只会在 run.py 中发布从 tkinter 启动 Flask 的代码:

def start(self):
        global p #global so can be accessed in stop function.
        p = Process(target=startFlask,)
        p.daemon=True
        p.start()            
        webbrowser.open(url='http:127.0.0.1:5000', new=2)

def startFlask():
        app.run()

pyinstaller 命令行是:

pyinstaller  -F --add-data "my_flask_app;my_flask_app" --onefile run.py

我已经尝试了一些变体,但不会走运。总之,只要不涉及 tkinter GUI,我就可以从 .exe 启动 Flask 应用程序。此外,我可以在我的开发环境中从 tkinkter GUI 启动 Flask 应用程序,但是正如我编译为 .exe 时所描述的那样,这会中断。

标签: pythonuser-interfaceflaskpython-multiprocessing

解决方案


这个问题的答案是使用“freeze_support()”。显然,在将使用多处理的 python 应用程序转换为 Windows 可执行文件时,这是必需的。我不完全明白为什么,但我很高兴现在一切正常!

https://docs.python.org/3/library/multiprocessing.html#multiprocessing.freeze_support


推荐阅读