tkinter:如何在同一处理程序中的小部件更改之间插入延迟?

tkinter:如何在同一处理程序中的小部件更改之间插入延迟?,tkinter,sleep,mainloop,Tkinter,Sleep,Mainloop,大约两年前,当我试图在Tkinter画布上模拟LED时,我问了一个类似的问题。然后,解决方案是使用canvas after()方法而不是sleep()函数在小部件更新之间引入延迟 从那以后,我发现了tk_工具模块,它有一个内置的功能来创建LED,太棒了!但我现在遇到了和以前一样的问题,那就是:每个LED的开启(变为绿色)之间如何有1秒的延迟 当运行下面的代码时,实际发生的情况是LED显示在关闭状态(灰色),然后当我单击“开始”按钮时,会有4秒钟的延迟,之后所有LED同时打开 多谢各位。 约翰尼姆

大约两年前,当我试图在Tkinter画布上模拟LED时,我问了一个类似的问题。然后,解决方案是使用canvas after()方法而不是sleep()函数在小部件更新之间引入延迟

从那以后,我发现了tk_工具模块,它有一个内置的功能来创建LED,太棒了!但我现在遇到了和以前一样的问题,那就是:每个LED的开启(变为绿色)之间如何有1秒的延迟

当运行下面的代码时,实际发生的情况是LED显示在关闭状态(灰色),然后当我单击“开始”按钮时,会有4秒钟的延迟,之后所有LED同时打开

多谢各位。 约翰尼姆


我猜每当回调函数完成执行时,所有的LED都会同时亮起。因此,我决定创建一个线程,并使用
after()
停止时间(
sleep()
停止主线程,使其持续4秒)


最好避免停止应用程序的睡眠,并在之后使用
。将调用链接到after回调,以便每个调用下一个,或在每个led的循环中调用它们,但延迟1、2、3、4秒

链接版本:

# LED array simulation

from tkinter import *
import tk_tools as tkt

# list to hold a 4-LED array
led_array = []

# GUI
root = Tk()

# create 4 LED widgets, store them in led_array[], display them
for i in range(4):
    led_array.append(tkt.Led(root, size=30))
    led_array[i].grid(row=0, column=i)

# Both answers are common to here.

def on_after( led_list ):
    led_list[0].to_green() # Set first item in the list.
    if len( led_list ) > 1:
        # Call on_after again with a shortened list.
        root.after( 1000, on_after, led_list[1:] )
    else:
        # Enable the start button
        start.config( state = NORMAL )

# turn on LEDs (change to green) with a 1-second delay between each
def turn_on():
    start.config( state = DISABLED ) # Disable the button
    root.after( 1000, on_after, led_array)

# create button to initiate LED turn-on sequence
start = Button(root, text='Start', padx=20, command=turn_on)
start.grid(row=1, columnspan=4)

root.mainloop()
# Both answers are common to here.
def on_after( led ):
    led.to_green()

def enable():
    start.config( state = NORMAL )

# turn on LEDs (change to green) with a 1-second delay between each
def turn_on():
    start.config( state = DISABLED ) # Disable the button
    for ix, led in enumerate( led_array ):
        # Call on_after 4 times with 1 to 4 second delays
        root.after( 1000 * (1+ix), on_after, led )
    root.after( 1000*(ix+1), enable )

# create button to initiate LED turn-on sequence
start = Button(root, text='Start', padx=20, command=turn_on)
start.grid(row=1, columnspan=4)

root.mainloop()
循环版本:

# LED array simulation

from tkinter import *
import tk_tools as tkt

# list to hold a 4-LED array
led_array = []

# GUI
root = Tk()

# create 4 LED widgets, store them in led_array[], display them
for i in range(4):
    led_array.append(tkt.Led(root, size=30))
    led_array[i].grid(row=0, column=i)

# Both answers are common to here.

def on_after( led_list ):
    led_list[0].to_green() # Set first item in the list.
    if len( led_list ) > 1:
        # Call on_after again with a shortened list.
        root.after( 1000, on_after, led_list[1:] )
    else:
        # Enable the start button
        start.config( state = NORMAL )

# turn on LEDs (change to green) with a 1-second delay between each
def turn_on():
    start.config( state = DISABLED ) # Disable the button
    root.after( 1000, on_after, led_array)

# create button to initiate LED turn-on sequence
start = Button(root, text='Start', padx=20, command=turn_on)
start.grid(row=1, columnspan=4)

root.mainloop()
# Both answers are common to here.
def on_after( led ):
    led.to_green()

def enable():
    start.config( state = NORMAL )

# turn on LEDs (change to green) with a 1-second delay between each
def turn_on():
    start.config( state = DISABLED ) # Disable the button
    for ix, led in enumerate( led_array ):
        # Call on_after 4 times with 1 to 4 second delays
        root.after( 1000 * (1+ix), on_after, led )
    root.after( 1000*(ix+1), enable )

# create button to initiate LED turn-on sequence
start = Button(root, text='Start', padx=20, command=turn_on)
start.grid(row=1, columnspan=4)

root.mainloop()

我可能会使用链式版本,尽管在这种情况下,循环式版本可能更容易理解。

很抱歉,我不熟悉OOP,因此我无法真正理解这个答案。我一直在寻找一种方法来解决这个问题,我使用的范例就是函数式编程。