在多处理之前调用 Tkinter 会导致多个窗口?
Posted
技术标签:
【中文标题】在多处理之前调用 Tkinter 会导致多个窗口?【英文标题】:Calling Tkinter before Multiprocessing causes multiple windows? 【发布时间】:2022-01-13 18:01:41 【问题描述】:我正在尝试使用 tkinter 使用 python 将一个较大的文件处理成几个较小的文件。发生的情况是我从批处理文件运行代码,系统提示我输入文件,我选择文件并点击确定,python 然后再打开 8 个文件对话框。如何让我的代码接受我的初始输入?据我所知,这不应该发生,因为文件对话框不在 multipro def 中。怎么回事?
代码类似于:
import tkinter, multiprocessing
from tkinter import filedialog
filename = filedialog.askopenfilename()
def multipro(num):
code.split(filename, num)
newfilename = filename + str(num) + fileextension
code.save(newfilename)
def MCprocess():
pool = multiprocessing.Pool(8)
pool.map(multipro, num)
if __name__ == '__main__':
num = list(range(1,10))
MCprocess()
sys.exit()
【问题讨论】:
【参考方案1】:您需要将filename = filedialog.askopenfilename()
放在if __name__ == '__main__':
中,这样它就不会被每个子任务执行。
由于每个进程都在自己的内存空间中运行,因此无法在进程之间共享全局变量。如果可行,最简单的做法是将数据作为参数传递给每个进程。由于传递给Pool.map()
的函数参数只能接受一个参数,因此我使用functools.partial
创建了一个基于multipro()
的临时函数,以传递已经提供给它的文件名。
这里有一个更全面的答案。我已经提供了许多您在问题代码中遗漏的未定义内容(因此我可以在答案中测试代码)。
from functools import partial
from pathlib import Path
import sys
def multipro(filename, num):
print(f'in multipro(filename=!r, num=)')
fileextension = Path(filename).suffix
code.split(filename, num)
newfilename = filename + str(num) + fileextension
code.save(newfilename)
def MCprocess(filename, nums):
func = partial(multipro, filename)
with multiprocessing.Pool(8) as pool:
pool.map(func, nums)
if __name__ == '__main__':
import tkinter, multiprocessing
from tkinter import filedialog
root = tkinter.Tk()
root.withdraw()
root.update()
filename = filedialog.askopenfilename()
root.destroy()
if filename: # User selected file?
nums = list(range(1,10))
MCprocess(filename, nums)
【讨论】:
这可以缓解 windows,但是我无法将文件名变量从 main 传递给 multipro def,因此脚本实际上并没有完成运行。我认为这不是正确的解决方案,或者说这不是一个令人满意的答案。 您的代码中有重复的行。 另外,我建议仅在filename
不是空字符串的情况下创建这些进程。并且sys.exit()
不是必需的。以上是关于在多处理之前调用 Tkinter 会导致多个窗口?的主要内容,如果未能解决你的问题,请参考以下文章
Python如何修复由于睡眠功能而导致的Tkinter窗口崩溃
OKHTTP Singleton 对象在多线程系统中处理不同的 API 调用
在 MS-Windows 下调整大小导致的 Tkinter 性能问题