【问题标题】:Calling Tkinter before Multiprocessing causes multiple windows?在多处理之前调用 Tkinter 会导致多个窗口?
【发布时间】: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()

【问题讨论】:

    标签: python tkinter multiprocessing


    【解决方案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() 不是必需的。
    猜你喜欢
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 2021-11-02
    • 2022-11-27
    • 1970-01-01
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    相关资源
    最近更新 更多