Tkinter陷入困境
mainloop。基本上,这意味着它会不断刷新窗口,等待单击按钮,键入单词,运行回调等。当您在打开的同一线程上运行某些代码
mainloop时,在此
mainloop之前,其他任何操作都不会执行代码部分完成。一个非常简单的解决方法是将一个长时间运行的进程生成到单独的线程上。这仍然可以与Tkinter进行通信并更新其GUI(大部分情况下)。
这是一个简单的示例,不会彻底修改您的伪代码:
import threadingclass Gui: [...]#costructor and other stuff def refresh(self): self.root.update() self.root.after(1000,self.refresh) def start(self): self.refresh() threading.Thread(target=doingALotOfStuff).start()#outsideGUI = Gui(Tk())GUI.mainloop()
该答案将详细介绍
mainloop如何阻止代码。
这是另一种方法,方法是在自己的线程上启动GUI,然后再运行不同的代码。
61
Bjorn发布的解决方案在我的计算机(RedHat Enterprise 5,python 2.6.1)上显示“ RuntimeError:从不同的公寓呼叫Tcl”消息。Bjorn可能没有得到此消息,因为据我检查过的一个地方,使用Tkinter处理线程是不可预测的且依赖于平台。
问题似乎是可以将其app.start()视为对Tk的引用,因为app包含Tk元素。我通过替换app.start()为self.start()inside来解决此问题__init__。我也这样做了,以便所有Tk引用都在调用mainloop()的函数内,或者在调用的函数所调用的函数内mainloop()(这对于避免“不同单元”错误很关键)。
最后,我添加了带有回调的协议处理程序,因为如果没有此处理程序,则当用户关闭Tk窗口时,程序会退出并出现错误。
修改后的代码如下:
# Run tkinter pre in another threadimport tkinter as tkimport threadingclass App(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.start() def callback(self): self.root.quit() def run(self): self.root = tk.Tk() self.root.protocol("WM_DELETE_WINDOW", self.callback) label = tk.Label(self.root, text="Hello World") label.pack() self.root.mainloop()app = App()print('Now we can continue running pre while mainloop runs!')for i in range(100000): print(i)


