tkinter:如何使用 after 方法
Posted
技术标签:
【中文标题】tkinter:如何使用 after 方法【英文标题】:tkinter: how to use after method 【发布时间】:2014-11-03 09:45:31 【问题描述】:嘿,我是 python 新手,我正在使用 tkinter 作为我的 gui。我在使用“之后”方法时遇到问题。 目标是每 5 秒随机出现一个字母。
这是我的代码:
import random
import time
from tkinter import *
root = Tk()
w = Label(root, text="GAME")
w.pack()
frame = Frame(root, width=300, height=300)
frame.pack()
L1 = Label(root, text="User Name")
L1.pack(side=LEFT)
E1 = Entry(root, bd =5)
E1.pack(side=LEFT)
tiles_letter = ['a', 'b', 'c', 'd', 'e']
while len(tiles_letter) > 0:
rand = random.choice(tiles_letter)
tile_frame = Label(frame, text=rand)
tile_frame.pack()
frame.after(500)
tiles_letter.remove(rand) # remove that tile from list of tiles
root.mainloop()
谁能帮帮我——问题肯定是 frame.after(500): 我不确定使用“框架”是否正确,也不知道 500 后面的参数是什么。
谢谢
【问题讨论】:
【参考方案1】:你需要给after
的第二个参数提供一个延时后调用的函数:
after(delay_ms, callback=None, *args)
注册一个在给定时间后调用的警报回调。
所以你真正想做的是:
tiles_letter = ['a', 'b', 'c', 'd', 'e']
def add_letter():
rand = random.choice(tiles_letter)
tile_frame = Label(frame, text=rand)
tile_frame.pack()
root.after(500, add_letter)
tiles_letter.remove(rand) # remove that tile from list of tiles
root.after(0, add_letter) # add_letter will run as soon as the mainloop starts.
root.mainloop()
您还需要通过在回调函数中重复调用after
来安排再次调用该函数,因为after
只执行给定函数一次。文档中也指出了这一点:
每次调用此方法时,只会调用一次回调。保持 调用回调,需要在里面重新注册回调 本身
请注意,一旦您用尽 tiles_letter
中的所有条目,您的示例就会抛出异常,因此您需要更改逻辑以按照您想要的方式处理这种情况。最简单的方法是在 add_letter
的开头添加一个检查以确保列表不为空,如果是则只需 return
:
def add_letter():
if not tiles_letter:
return
rand = random.choice(tiles_letter)
tile_frame = Label(frame, text=rand)
tile_frame.pack()
root.after(500, add_letter)
tiles_letter.remove(rand) # remove that tile from list of tiles
现场演示:repl.it
【讨论】:
第一次调用不需要使用after
,尤其是after(0, ...)
。【参考方案2】:
我相信,这 500 毫秒在后台运行,而其余代码继续执行并清空列表。
然后在 500 毫秒后什么都没有发生,因为在后调用中没有实现任何函数调用(与 frame.after(500, function=None)
相同)
【讨论】:
以上是关于tkinter:如何使用 after 方法的主要内容,如果未能解决你的问题,请参考以下文章
在 tkinter 的 Tk.after() 方法中使用 async/await 关键字