我正在尝试创建一个简单的东西:一个在迭代之间延迟 x 秒的循环,由 Tkinter 按钮命令触发。
显而易见的答案是使用 time.sleep()
,但是,这实际上卡住了 mainloop
进程,避免捕获其他事件。
我搜索过,建议使用 tkinter.after()
方法,但是,我仍然无法让循环在迭代之间花费时间。
有什么帮助吗?简化代码如下。
import tkinter as tk
import tkinter.scrolledtext as st
import time
# function to be activated by button
def do_some_action():
for i in range(10):
# just write some variable text to check if it is working
txt_bigtextlog.insert(tk.END,'Row text {} off 10\n'.format(i))
# tk.END to point the scrolling text to latest line
txt_bigtextlog.see(tk.END)
# I´ve tried w/o success (1000 is miliseconds):
# mywindowapp.after(1000)
# btn_action.after(1000)
time.sleep(1)
mywindowapp.update()
return()
# Create the application main window
mywindowapp = tk.Tk()
# create some label, just to visualize something
lbl_justsomelabel = tk.Label(text='Just some label here')
lbl_justsomelabel.grid(row=0,column=0,sticky='NSEW',padx=10,pady=10)
# create a button, just so simulate loop triggering
btn_action = tk.Button(text='Start process',command=do_some_action)
btn_action.grid(row=1,column=0,sticky='NSEW',padx=10,pady=10)
# create a scrolling text just to do some example iterable action
txt_bigtextlog = st.ScrolledText(mywindowapp,width = 30,height = 8)
txt_bigtextlog.grid(row=2,column = 0, columnspan=3,sticky='NSEW', pady = 10, padx = 10)
txt_bigtextlog.insert(tk.INSERT,'')
mywindowapp.mainloop()
最佳答案
基本概念是编写一个函数来执行循环的一次迭代,然后安排自身在将来未满足某些条件时再次运行。为此,您可以将循环计数器初始化为关键字参数,并且您可以在每次函数安排自身再次运行时增加该值。
def do_some_action(i=0):
# just write some variable text to check if it is working
txt_bigtextlog.insert(tk.END,'Row text {} off 10\n'.format(i))
# tk.END to point the scrolling text to latest line
txt_bigtextlog.see(tk.END)
if i+1 < 10:
txt_bigtextlog.after(1000, do_some_action, i+1)
当您单击按钮时,do_some_action
会在没有参数的情况下被调用。这导致 i
被初始化为零。它执行循环的一次迭代,然后安排自己在条件未满足时再次调用。每次它自己安排时,它都会向 i
添加一个。
关于python - 如何使用 Tkinter .after() 方法来延迟循环而不是 time.sleep()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74214619/