首页 > 解决方案 > 如何使用多处理启动一个单独的新 Tk() 窗口?

问题描述

以下代码是可运行的,您只需复制/粘贴即可:

from tkinter import *
import multiprocessing

startingWin = Tk()
def createClientsWin():
    def startProcess():
        clientsWin = Tk()
        label = Label(clientsWin, text="Nothing to show")
        label.grid()
        clientsWin.mainloop()
    if __name__ == "__main__":
        p = multiprocessing.Process(target=startProcess)
        p.start()
button = Button(startingWin, text="create clients", command=lambda: createClientsWin())
button.grid()
startingWin.mainloop()

所以我只想Tk()使用多处理创建一个完全分离的窗口。当我单击创建按钮时,我只得到原始窗口(不是预期的窗口),它给了我这个错误:

AttributeError: Can't pickle local object 'createClientsWin.<locals>.startProcess'

*有人可以解释如何使用多处理启动一个单独的新 Tk() 窗口吗?*

更新:不是重复的

即使我遵循可能重复的问题中提供的解决方案,这也无助于解决我的问题。仅仅因为在我的案例中使用了 Tkinter。修改后的代码:

def createClientsWin():
    clientsWin = Tk()
    label = Label(clientsWin, text="Nothing to show")
    label.grid()
    clientsWin.mainloop()

def createClientsWinProcess():
    if __name__ == "__main__":
        p = multiprocessing.Process(target=createClientsWin)
        p.start()

startingWin = Tk()
button = Button(startingWin, text="create clients", command=lambda: createClientsWinProcess())
button.grid()
startingWin.mainloop()

标签: pythonpython-3.xtkintermultiprocessing

解决方案


全局范围内的函数应用于多进程目标函数,因此startProcess()应将其移至全局范围内。

此外,if __name__ == "__main__"内部检查startProcess()将导致 if 块内的代码不被执行。

最后创建startingWin应该放在if __name__ == "__main__"块内,否则每个启动的进程都会创建startingWin.

以下是解决上述问题的建议更改:

from tkinter import *
import multiprocessing

def startProcess():
    clientsWin = Tk()
    label = Label(clientsWin, text="Nothing to show")
    label.grid()
    clientsWin.mainloop()

def createClientsWin():
    p = multiprocessing.Process(target=startProcess)
    p.start()

if __name__ == '__main__':
    startingWin = Tk()
    button = Button(startingWin, text="create clients", command=createClientsWin)
    button.grid()
    startingWin.mainloop()

推荐阅读