我有一个使用Tkinter作为GUI的Python脚本。我的小脚本应该每X秒创建一个顶级小部件。当我运行代码时,第一个“顶级”窗口小部件被成功创建,但是当它尝试创建第二个“窗口小部件”时,程序崩溃。
我正在做的是使用after方法每隔5秒钟与root的mainloop一起调用一次函数startCounting。每次调用此函数时,我都会将Toplevel小部件对象追加到列表中并启动一个新线程,该线程有望运行新的mainloop。
如果有人能解决这个问题,我将不胜感激。顺便说一下,这只是我目前用来解决问题的一个小脚本,这使我无法继续进行实际的学校项目。
编码:
import threading,thread from Tkinter import * def startCounting(): global root global topLevelList global classInstance topLevelList.append (Toplevel()) topLevelList[len(topLevelList)-1].title("Child") classInstance.append(mainLoopThread(topLevelList[len(topLevelList)-1])) root.after(5000,startCounting) class mainLoopThread(threading.Thread): def __init__(self,toplevelW): self.toplevelW = toplevelW threading.Thread.__init__(self) self.start() def run(self): self.toplevelW.mainloop() global classInstance classInstance = [] global topLevelList topLevelList = [] global root root = Tk() root.title("Main") startCounting() root.mainloop()
Tkinter设计为仅从主线程运行。见文档:
只需在主线程中运行所有UI代码,然后让编写者将其写入Queue对象即可;例如
……然后是一个重要的示例,显示了辅助线程将请求写入队列,而主循环专门负责与Tk的所有直接交互。
许多对象和子系统不喜欢接收来自多个线程的请求,在使用GUI工具箱的情况下,不需要专门使用 主 线程。
解决此问题的正确Python架构始终是为服务挑剔的对象或子系统分配一个线程(如果需要,则使用一个主线程)。所有其他需要与所述子系统或对象进行交互的线程都必须通过将请求排队到专用线程来获得它(如果由于某些请求而需要结果,则可能在“返回队列”中等待结果)。这也是用于通用线程的非常完善的Python体系结构(我在“坚果壳中的Python”中对此进行了详尽的阐述,但这是另一个主题;-)。