【问题标题】:How to start a separate new Tk() window using multiprocessing?如何使用多处理启动一个单独的新 Tk() 窗口?
【发布时间】:2019-08-06 06:15:21
【问题描述】:

以下代码是可运行的,你可以复制/粘贴:

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

【问题讨论】:

  • @CommonSense 不是重复的。请检查上面的编辑。
  • 您的最终目标是什么?根据操作系统,可能无法在分叉进程中运行 Tk(这就是多处理所做的)。
  • @AKX 操作系统是 Win7。 Win7可以吗?
  • 你应该把startProcess()移到createClientsWin()之外,去掉if __name__ == "__main__"里面createClientsWin()的检查。最后在创建startingWin 之前添加检查if __name__ == "__main__"

标签: python python-3.x tkinter multiprocessing


【解决方案1】:

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

另外,检查startProcess() 内的if __name__ == "__main__" 将导致 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()

【讨论】:

    【解决方案2】:

    在 tkinter 中使用多处理时使用类更容易。试试下面的代码:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-25
      • 2016-01-04
      • 2018-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多