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 方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在使用 .after 时更新 GUI?

在 tkinter 的 Tk.after() 方法中使用 async/await 关键字

如何在函数后停止 tkinter?

Python tkinter:动态显示信息的两种方式「最详细解答」

tkinter。after serial read挂断

Tkinter:在主循环中调用事件