[英]Fail to “blink”/ change color of tkinter widget when using `after`
I'm trying to simulate a blink of a label widget by changing its color in this manner: 我试图通过以这种方式更改其颜色来模拟标签小部件的闪烁:
a) change to color #1, pause 1 sec, a)更改为颜色1,暂停1秒,
b) change to color #2, pause 1 sec, b)更改为颜色2,暂停1秒钟,
c) loop again using tk.after
to rerun this procedure. c)使用
tk.after
再次循环以重新运行此过程。
But the result is a constant color, #2. 但是结果是恒定的颜色#2。
self.blink_status
is an index telling communication status is OK, and equals to 1
. self.blink_status
是一个指示通信状态为OK的索引,等于1
。 of course code was tested with a constant value self.blink_status=1
当然,代码已使用常量
self.blink_status=1
进行了测试
def blink_tx(self):
if self.blink_status == 1:
self.tx_label["bg"] = 'green'
self.tx_value.set('Tx')
sleep(1)
self.tx_label["bg"] = 'blue'
sleep(1)
elif self.blink_status == 0:
self.tx_label["bg"] = 'red'
self.tx_value.set('*')
sleep(2)
self.tx_label["bg"] = 'orange'
else:
self.tx_label["bg"] = 'red'
self.tx_value.set('x')
sleep(2)
self.status_frame.after(3500, self.blink_tx)
the way self.tx_label
and self.tx_value
are defined : self.tx_label
和self.tx_value
的定义方式:
self.tx_label = tk.Label(self.status_frame, textvariable=self.tx_value, relief=tk.GROOVE, width=2)
self.tx_label.grid(row=0, column=4, sticky=tk.E)
You cannot use sleep()
inside of a tkinter instance. 您不能在tkinter实例内部使用
sleep()
。 Tkinter is a single thread application and when you tell it to sleep everything in the event list is put on hold/freezes. Tkinter是一个单线程应用程序,当您告诉它进入睡眠状态时,事件列表中的所有内容都将保持/冻结状态。 You need to use
after()
for any delays in your code. 您需要使用
after()
来延迟代码。 The after()
method is specifically meant to manage delays in tkinter. after()
方法专门用于管理tkinter中的延迟。
Because in your example it appears you are running 2 separate delays my example will provide both delays. 因为在您的示例中您似乎正在运行2个单独的延迟,所以我的示例将同时提供这两个延迟。
Here is an exampled composed from the code you provided. 这是由您提供的代码组成的示例。 We can set all the delays we need buy provided a 2nd function.
我们可以设置第二功能来设置所有需要购买的延迟时间。 I have added a random number generator to the code to illustrate a continuous change of the colors.
我在代码中添加了一个随机数生成器,以说明颜色的连续变化。
import tkinter as tk
import random
class MainApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.tx_value = tk.StringVar()
self.tx_value.set("test")
self.blink_status = 1
self.tx_label = tk.Label(self, textvariable=self.tx_value, relief=tk.GROOVE, width=4, height=2)
self.tx_label.grid(row=0, column=4, sticky=tk.E)
self.blink_tx()
def blink_tx_step_2(self, color=None):
if color != None:
self.tx_label["bg"] = color
self.after(3500, self.blink_tx)
def blink_tx(self):
if self.blink_status == 1:
self.tx_label["bg"] = 'green'
self.tx_value.set('Tx')
self.blink_status = random.randint(0, 2)
self.after(1000, self.blink_tx_step_2, 'blue')
elif self.blink_status == 0:
self.tx_label["bg"] = 'red'
self.tx_value.set('*')
self.blink_status = random.randint(0, 2)
self.after(2000, self.blink_tx_step_2, 'orange')
else:
self.tx_label["bg"] = 'red'
self.tx_value.set('x')
self.blink_status = random.randint(0, 2)
self.after(2000, self.blink_tx_step_2)
if __name__ == '__main__':
app = MainApp()
app.mainloop()
time.sleep()
is blocking your GUI updates; time.sleep()
阻止您的GUI更新; do not use it with a GUI. 不要将其与GUI一起使用。 Use
root.after
instead. 请改用
root.after
。
The following label will start blinking when you click on the GUI: 当您单击GUI时,以下标签将开始闪烁:
You can adapt it to your own code that was not provided. 您可以将其调整为未提供的自己的代码。
import tkinter as tk
class BlinkerLabel(tk.Label):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.status = 1
def blink(self, event):
if self.status == 1:
self["bg"] = 'green'
elif self.status == 0:
self["bg"] = 'red'
self.status = (self.status + 1) % 2
self.after(3500, self.blink, 'dummy_event') # <-- this creates the 'delay' between blinks
if __name__ == '__main__':
root = tk.Tk()
lbl = BlinkerLabel(root, text='I blink!')
lbl.pack()
root.bind('<Button-1>', lbl.blink)
root.mainloop()
Thanks for @Mike-SMT and @Reblochon Masque for helping. 感谢@ Mike-SMT和@Reblochon Masque的帮助。 TNX ALOT
TNX很多
My code fix: 我的代码修复:
def blink_tx(self):
def blink_1(color1, color2, txt):
self.tx_label["bg"] = color1
self.tx_value.set(txt)
self.after(t_blink, blink_2, color2)
def blink_2(color):
self.tx_label["bg"] = color
self.after(t_blink, self.blink_tx)
t_blink = 2500
if self.blink_status == 1:
blink_1('green', 'orange', 'Tx')
elif self.blink_status == 0:
blink_1('red', 'yellow', '*')
else:
blink_1('red', 'red', 'X')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.