对tkin使用after方法

2024-06-26 14:51:29 发布

您现在位置:Python中文网/ 问答频道 /正文

如有人建议,我开始用.后的方法创建弹跳球GUI,又一次成了一个问题。在

from tkinter import*
from tkinter import ttk
import random


class Widg:
    def __init__(self, master):
        master.geometry('600x500+200+150')
        canvas = Canvas(master)
        canvas.pack(fill=BOTH, expand=True)
        oval = canvas.create_oval(1, 1, 11, 11, fill='green')

        def call_func(self):
            for i in range(3):
                rand_x = random.randint(1, 50)
                rand_y = random.randint(1, 50)
                canvas.move(oval, rand_x, rand_y)
                canvas.after(500)
                print('x= ', rand_x)
                print('y= ', rand_y)

        canvas.bind('<ButtonPress-1>', call_func)


def main():

    root = Tk()

    a = Widg(root)

    root.mainloop()


if __name__ == '__main__':
    main()

再次,当我启动它时,它运行在小部件后面,并简单地显示最终结果。(无动画)

升级版: upd2.:@tobias_k正式注明!不会再发生了!谢谢你的回答!在


Tags: fromimportselfmastermaintkinterdefrandom
1条回答
网友
1楼 · 发布于 2024-06-26 14:51:29

您必须指定要在after中调用的函数,在您的示例中,它是在同一个函数中调用的。如前所述,in comments,如果没有回调函数,after的行为与sleep相同(除了参数是以毫秒为单位而不是以秒为单位),也就是说,它将等待给定的时间,但这样做会阻塞UI,这样就不会注册任何输入,尤其是在循环之后才会重新绘制球。通过使用回调调用after,您可以无限期地再次调用该函数,每次重新定位和重新绘制球。在

另外,请注意call_func的参数是而不是self(就像在原始代码中一样),它不是类的一个方法,而是一个嵌套函数,而是鼠标单击发出的event。您应该将此参数设为默认参数,因为使用after时不会发生任何事件(您也不需要它)。而且,似乎不需要循环;如果您希望球移动得更快,请减少after中的时间,并且对于rand_x/y变量使用self是没有意义的。在

def call_func(event=None):
    rand_x = random.randint(-50, 50)
    rand_y = random.randint(-50, 50)
    self.canvas.move(self.oval, rand_x, rand_y)
    self.canvas.after(150, call_func)

如果您希望函数只回调有限的次数,可以添加另一个参数,跟踪重复次数:

^{pr2}$

相关问题 更多 >