首页 > 解决方案 > 如何在 Tkinter 中使用 .after 使按钮闪烁?

问题描述

我是一个初学者,正在使用 Tkinter 和 Python 制作一个简单的 Simon 游戏。我已经弄清楚了逻辑,但是,我真的很难让按钮闪烁以向播放器显示序列。我在这里做的是让它循环通过按钮序列,当它循环通过时,它会相应地闪烁正确的按钮。但是,无论我做什么,我都无法让按钮闪烁白色,也就是说,它似乎跳过了将 bg 更改为白色的 configure 方法,而只执行了将 bg 更改为红色/蓝色/绿色/黄色的配置。

我在一个简单的程序中对此进行了测试,该程序应该在我按下按钮后闪烁一个标签,但同样的故事。它只是不会做第一个配置,似乎只做第二个。因此,如果我告诉它将标签更改为白色,然后等待 200 毫秒,然后将其更改为蓝色,它只会在 200 毫秒后将其更改为蓝色。

        for x in cpu_sequence:

            if x == "A":
                a_butt.after(200)
                a_butt.configure(bg="white")
                a_butt.after(200)
                a_butt.configure(bg="red")


            elif x == "B":
                b_butt.after(200)
                b_butt.configure(bg="white")
                b_butt.after(200)
                b_butt.configure(bg="green")


            elif x == "C":
                c_butt.after(200)
                c_butt.configure(bg="white")
                c_butt.after(200)
                c_butt.configure(bg="blue")


            elif x == "D":
                d_butt.after(200)
                d_butt.configure(bg="white")
                d_butt.after(200)
                d_butt.configure(bg="yellow")

它应该等待 200 毫秒,将按钮更改为白色,然后等待 200 毫秒,然后将按钮更改回其原始颜色(红色、绿色、蓝色或黄色)。

标签: pythontkinter

解决方案


after使用单个参数与调用没有什么不同time.sleep——它会导致应用程序冻结。但是,如果您提供after的参数不仅仅是毫秒数,它会在给定的延迟后将该参数作为函数调用。

如果您只想在 200 毫秒内更改背景,然后在 200 毫秒后再次更改(例如:调用函数后 400 毫秒),您可以同时安排这两个命令。然后 Tkinter 将在适当的时候调用这些函数。

label.after(200, lambda: label.configure(background="white"))
label.after(400, lambda: label.configure(background="yellow"))

注意:lambda在这里使用是因为不可能通过after. lambda是一种提供无名可调用对象的方法after。如果我们调用一个不需要关键字参数的函数,那lambda将是不必要的。

例如:

def set_color(label, color):
    label.configure(background=color)

label.after(200, set_color, label, "white")
label.after(400, set_color, label, "yellow")

这是一个完整的例子:

import tkinter as tk
def flash():
    root.after(200, lambda: label.configure(background="white"))
    root.after(400, lambda: label.configure(background="yellow"))

root = tk.Tk()
label = tk.Label(root, text="Hello", background="yellow")
button = tk.Button(root, text="Flash!", command=flash)
label.pack(side="top", fill="x")
button.pack(side="bottom", padx=20, pady=20)

root.mainloop()

推荐阅读