在多处理之前调用 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窗口崩溃

在多窗口 UWP 应用中引发和处理事件

OKHTTP Singleton 对象在多线程系统中处理不同的 API 调用

在 MS-Windows 下调整大小导致的 Tkinter 性能问题

Python中tkinter的窗口,在mainloop ()之后的语句怎么执行啊、循环以后就不动

tkinter窗口鼠标拖动就会暂停