一般来说,您不能在 Tkinter 应用程序中放置无限循环。为什么?它已经在运行一个无限循环:事件循环。您的代码相当于:
while <there are more events to service>:
while True:
<run code in here>
<get the next event>
<service the event>
看到问题了吗?您正在阻止代码为事件提供服务,而事件是 GUI 的生命线。
相反,您需要通过添加要在循环内运行的代码来利用已经运行的无限循环。您可以使用after
(and after_idle
) 执行此操作。这将把一个甚至放在队列中。如果在处理该事件期间您再次调用after_idle
,则您有效地设置了一个在事件循环内工作的无限循环。
例如:
def do_one_iteration(self):
<run code in here>
self.after(100, self.do_one_iteration)
然后,在你的主逻辑的某个地方,或者响应一个按钮,你调用do_one_iteration
. 它将对您以前的无限循环进行一次迭代。完成后,它会指示 Tkinter 在 100 毫秒后再次调用自己。当该时间段过去时,您的代码将运行,它会在 100 毫秒内安排另一次迭代,等等。您可以将间隔更改为您想要的任何时间;间隔越小,您的代码运行得越快,但您让 GUI 无法获得事件的机会就越大。
请注意,这仅在<run code in here>
运行相对较快时才有效。当它运行时,您的 GUI 将冻结。如果它可以在几百毫秒内完成一次迭代,那么用户永远不会知道。如果它需要一秒钟或更长时间,它会很明显。
注意:此示例假设您的主应用程序是一个继承自 Tkinter 小部件的对象。如果不是这种情况,它仍然可以工作,你只需要删除self
参数。一个更好的解决方案是重构您的 GUI 以使用对象——这是一种更灵活的实现 GUI 的方式。