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:
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.