Python tkinter:如何使用 after 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25753632/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 23:36:00  来源:igfitidea点击:

tkinter: how to use after method

pythonuser-interfacetkinterpycharm

提问by user2456977

Hey I am new to python and am using tkinter for my gui. I am having trouble using the "after" method. The goal is to make a random letter appear every 5 seconds.

嘿,我是 python 新手,我的 gui 使用 tkinter。我在使用“after”方法时遇到问题。目标是每 5 秒随机出现一个字母。

Here is my code:

这是我的代码:

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()

can someone please help me --- the problem is definitely frame.after(500): i'm not sure if it is correct to use "frame" and I don't know what which argument follows the 500.

有人可以帮我 --- 问题肯定是 frame.after(500):我不确定使用“frame”是否正确,我不知道 500 后面是什么参数。

Thanks

谢谢

采纳答案by dano

You need to give a function to be called after the time delay as the second argument to after:

您需要提供一个在时间延迟后调用的函数作为第二个参数after

after(delay_ms, callback=None, *args)

Registers an alarm callback that is called after a given time.

after(delay_ms, callback=None, *args)

注册在给定时间后调用的警报回调。

So what you really want to do is this:

所以你真正想做的是:

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()

You also need to schedule the function to be called again by repeating the call to afterinside the callback function, since afteronly executes the given function once. This is also noted in the documentation:

您还需要通过after在回调函数内部重复调用来安排再次调用该函数,因为after只执行一次给定的函数。这在文档中也有说明:

The callback is only called once for each call to this method. To keep calling the callback, you need to reregister the callback inside itself

每次调用此方法时只调用一次回调。要继续调用回调,您需要在其内部重新注册回调

Note that your example will throw an exception as soon as you've exhausted all the entries in tiles_letter, so you need to change your logic to handle that case whichever way you want. The simplest thing would be to add a check at the beginning of add_letterto make sure the list isn't empty, and just returnif it is:

请注意,一旦您用尽 中的所有条目,您的示例就会抛出异常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


Live-Demo: repl.it

现场演示:repl.it