使用`after`

时间:2018-06-14 13:41:32

标签: python 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)

3 个答案:

答案 0 :(得分:4)

您不能在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()

答案 1 :(得分:3)

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

答案 2 :(得分:0)

感谢@ 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')