pyinstaller,每个约翰里布布并行呼叫都会在macOS上创建一个新的tkinter窗口

发布于 2025-01-30 18:13:25 字数 914 浏览 5 评论 0原文

这是可以重现问题的代码(仅是为了重现问题,因此它的作用有点毫无意义):

from joblib import Parallel, delayed
import tkinter as tk


def f():
    print('func call')


if __name__ == '__main__':
    root = tk.Tk()

    button = tk.Button(root,
                       command=lambda: Parallel(n_jobs=-1, backend='threading')(delayed(f)() for _ in range(1)),
                       text='func')
    button.pack()

    root.mainloop()

上面的代码可以在我的IDE中完美运行,但是一旦我用Pyinstaller创建可执行文件,它就会破坏。 创建可执行文件的命令行如下:

pyinstaller -F main.py

例外的行为是,每当按tkinter窗口中的按钮时终端。但是,当我使用可执行文件运行时,每次按下按钮,除了终端中的打印外,还创建了一个新的tkinter窗口。

我还尝试使用同一命令在Windows中构建可执行文件。可执行文件在Windows中运行良好(在按下按钮时未创建新的tkinter窗口)。只有MacOS平台才有这个问题。

我应该如何解决此问题?

这是我有问题的平台:

  • CPU:ARM64(M1)
  • Python:3.10
  • Joblib:1.1.0
  • Pyinstaller 5.0.1

Here is the code which can reproduce the problem (it is just for reproducing the problem, so what it does is a bit meaningless):

from joblib import Parallel, delayed
import tkinter as tk


def f():
    print('func call')


if __name__ == '__main__':
    root = tk.Tk()

    button = tk.Button(root,
                       command=lambda: Parallel(n_jobs=-1, backend='threading')(delayed(f)() for _ in range(1)),
                       text='func')
    button.pack()

    root.mainloop()

The above code can run perfectly in my IDE, but once I create an executable with Pyinstaller, it bugs.
The command line to create the executable is as below:

pyinstaller -F main.py

The excepted behavior is that, every time when presses the button in the tkinter window, a func call string should be printed in the terminal. But when I use the executable file to run, every time I press the button, besides the printing in the terminal, a new tkinter window is created.

I have also tried to build the executable in Windows with the same command. The executable file runs fine in Windows (No new tkinter window is created when pressing the button). Only the MacOS platform has this problem.

How should I fix this?

Here is the platform that I have the problem:

  • CPU: ARM64 (M1)
  • Python: 3.10
  • joblib: 1.1.0
  • pyinstaller 5.0.1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

新人笑 2025-02-06 18:13:25

通过将multiprocessing.freeze_support()添加到代码来解决问题。固定版本的代码如下:

import multiprocessing
multiprocessing.freeze_support()

from joblib import Parallel, delayed
import tkinter as tk


def f():
    print('func called')


if __name__ == '__main__':
    root = tk.Tk()

    button = tk.Button(root,
                       command=lambda: Parallel(n_jobs=-1, backend='threading')(delayed(f)() for _ in range(1)),
                       text='func')
    button.pack()

    root.mainloop()

谢谢 rokm 回答了我在github上的问题,这是 rokm's 的URL答案: https://github.com/pyinstaller/pyinstaller/pyinstaller/pyinstaller/issues/6852#issuecomment-1113826938888

The problem is solved by adding multiprocessing.freeze_support() to the code. The fixed version of code is as below:

import multiprocessing
multiprocessing.freeze_support()

from joblib import Parallel, delayed
import tkinter as tk


def f():
    print('func called')


if __name__ == '__main__':
    root = tk.Tk()

    button = tk.Button(root,
                       command=lambda: Parallel(n_jobs=-1, backend='threading')(delayed(f)() for _ in range(1)),
                       text='func')
    button.pack()

    root.mainloop()

Thank you rokm for answering my question on GitHub, here is the URL to rokm's answer: https://github.com/pyinstaller/pyinstaller/issues/6852#issuecomment-1138269358.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文