How to start a separate new Tk() window using multiprocessing?

≡放荡痞女 提交于 2020-02-25 04:11:24

问题


The following code is runnable, you can just copy/paste:

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()

So I simply want to create a completely separated Tk() window using multiprocessing. When I click on the create button, I just get the original window (not the intended one) and it gives me this error:

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

*Could someone explain how to start a separate new Tk() window using multiprocessing? *

Update: Not A Duplicate

Even if I follow the solution provided in the possible duplicate question, that doesn't help solving my question. Simply because, Tkinter is being used in my case. The modified code:

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()

回答1:


Function in global scope should be used for multiprocess target function, so the startProcess() should be moved into global scope.

Also the checking of if __name__ == "__main__" inside startProcess() will cause the code inside the if block not being executed.

Finally the creation of startingWin should be put inside if __name__ == "__main__" block, otherwise every process started will create the startingWin.

Below is the proposed changes to solve the above issues:

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()



回答2:


It is easier to use classes when using multiprocessing with tkinter. Try the following code:

import tkinter as Tk
import multiprocessing as mp

class A:
    def __init__(self, master):
        self.master = master

        label = Tk.Label(self.master, text = 'A')
        label.pack()

        root_b = Tk.Toplevel()
        GUI_B = B(root_b)
        mp.Process(target = GUI_B.mainloop())

    def mainloop(self):
        self.master.mainloop()

class B:
    def __init__(self, master):
        self.master = master

        label = Tk.Label(self.master, text = 'B')
        label.pack()

    def mainloop(self):
        self.master.mainloop()

if __name__=='__main__':
    root = Tk.Tk()
    GUI_A = A(root) 
    mp.Process(target = GUI_A.mainloop())


来源:https://stackoverflow.com/questions/55177983/how-to-start-a-separate-new-tk-window-using-multiprocessing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!