使用"之后"时无法"blink"/更改tkinter小部件的颜色



我试图通过以这种方式更改标签小部件的颜色来模拟标签小部件的眨眼:

a( 更改为颜色 #1,暂停 1 秒,

b( 更改为颜色 #2,暂停 1 秒,

c( 使用tk.after再次循环以重新运行此过程。

但结果是恒定的颜色,#2。

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)

定义self.tx_labelself.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)

您不能在 tkinter 实例中使用sleep()。Tkinter 是一个单线程应用程序,当您告诉它休眠时,事件列表中的所有内容都会被搁置/冻结。您需要对代码中的任何延迟使用after()after()方法专门用于管理 tkinter 中的延迟。

因为在您的示例中,您似乎正在运行 2 个单独的延迟,我的示例将提供两个延迟。

下面是由您提供的代码组成的示例。 我们可以设置我们需要购买的所有延迟,前提是第二个功能。我在代码中添加了一个随机数生成器来说明颜色的连续变化。

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()会阻止您的 GUI 更新;不要将其与 GUI 一起使用。请改用root.after

当您单击 GUI 时,以下标签将开始闪烁:
您可以将其调整为未提供自己的代码。

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()

感谢@Mike-SMT和@Reblochon Masque的帮助。TNX ALOT

我的代码修复:

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')

最新更新