Python 使用'after'时无法“闪烁”/更改tkinter小部件的颜色`

Python 使用'after'时无法“闪烁”/更改tkinter小部件的颜色`,python,tkinter,Python,Tkinter,我试图通过以下方式更改标签小部件的颜色来模拟其闪烁: 更改为颜色1,暂停1秒 b换成颜色2,暂停1秒 使用tk.after再次循环以重新运行此过程 但是结果是一个恒定的颜色,2 self.blink_status是一个指示通信状态正常的索引,等于1。当然,代码是用一个常量值self进行测试的。blink_status=1 self.tx_标签和self.tx_值的定义方式: self.tx_label = tk.Label(self.status_frame, textvariable=self

我试图通过以下方式更改标签小部件的颜色来模拟其闪烁:

更改为颜色1,暂停1秒

b换成颜色2,暂停1秒

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

但是结果是一个恒定的颜色,2

self.blink_status是一个指示通信状态正常的索引,等于1。当然,代码是用一个常量值self进行测试的。blink_status=1

self.tx_标签和self.tx_值的定义方式:

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

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

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

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

感谢@Mike SMT和@Reblochon Masque的帮助。大量TNX

我的代码修复程序:

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

请考虑添加一个代码示例,或者修改您在这个问题中发布的代码。目前,它的格式和范围使我们很难帮助您;这是一个让你开始学习的方法。祝你的代码好运@ReblochonMasque-我只想带一些相关的代码,关于blink本身,我会更新,让大家更容易理解,因为你在代码中使用了sleep。这本身将导致应用程序冻结,无法按预期工作。@Mike SMT这就是为什么我要在之后使用它,以允许代码继续运行,而不考虑睡眠。否。事实并非如此。从代码中完全删除睡眠。您需要在blink_tx内创建一个新函数,使用after方法调用。在tkinter实例内不能使用sleep。您可以在tkinter iInstance之外的单独线程中使用它,但不能在内部使用。谢谢。据我所知,按钮按下事件将导致闪烁,如何在无需按下的情况下连续进行?使用GUI中的指示灯泡否,此闪烁标签将每3500毫秒持续闪烁一次。哦。现在我理解了模的部分是的,模是从状态=0切换到状态=1这似乎是一个数学家用模来解决的方法!,但在我的例子中,self.status是ping测试的结果,结果是1。这意味着每个时间周期的值都可以是0,1,NULL。我怎么能这样使用模数呢?太好了,我不认为输入数后是允许的。愚蠢的我:@Guy.D after方法只会在事件列表中添加一个命令,并会告诉tkinter在经过设定的时间之前不要执行该命令。它不能保证这会在你提到的确切时间内发生,但它能保证它不会在你提到的时间之前发生。你们都是:
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')