在我的程序中,我的GUI类中有一个方法,我希望定期更新GUI。下面是我的代码的简化版本。
from tkinter import *
from time import sleep
class GUI_Class:
def __init__(self, parent):
self.var = IntVar()
scale = Scale(parent, to = 1, variable = self.var)
scale.pack()
self.label = Label(parent, bg = "white")
self.label.pack()
button = Button(parent)
button.pack()
button.bind("<Button-1>",lambda event:self.change_colour())
def change_colour(self):
if self.var.get() == 1:
counter = 0
while self.var.get() == 1 and counter != 20:
self.label.configure(bg = "red")
self.label.update_idletasks()
sleep(0.5)
self.label.configure(bg = "blue")
self.label.update_idletasks()
sleep(0.5)
counter += 1
else:
self.label.configure(bg = "white")
root = Tk()
GUI = GUI_Class(root)
root.mainloop()
问题是,当用于更改GUI的while循环正在运行时,程序在等待while循环结束时会失去所有功能。我看过其他人问题的答案,所有的答案都建议线程化,但在答案中的例子中,它总是在一个单独的线程中运行另一个类的方法。虽然我可以用读取GUI.label.config(bg="color(的命令创建一个单独的类并在它自己的线程中运行它——这个程序的评估是,类之间必须有最小的交互,所以拥有一个完全目的是改变在另一个类中创建的GUI布局的类可能会降低我的分数。我想知道的是,是否有一种方法可以在它所属的类的单独线程中运行一个方法,从而使我的while循环在GUI的其余部分仍在运行时运行,即当标签在蓝色和红色之间闪烁时。用户可以将比例更改为0,按下按钮并停止循环?
Tkinter提供了一个after
方法,允许您安排命令在几毫秒后运行。在after处理程序中,您可以检查状态,进行适当的修改,并安排对同一处理程序的另一次调用。这是因为您从未阻止正在运行的UI线程,而是安排对方法的定期调用。
after
方法返回一个令牌,该令牌可用于取消计划的任务。因此,只要您保留该令牌,就可以将其传递给after_cancel
方法以取消未完成的计划调用。