繁体   English   中英

与tkinter一起使用after方法

[英]using after method with tkinter

正如建议的那样,我开始使用.after方法来创建弹跳球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()

同样,当我启动它时,它在小部件后面运行,并仅显示最终结果。 (无动画)

upd .: upd2 :: @ tobias_k正确记录! 不会再发生了! 感谢您的回答!

您必须指定要在after调用的函数-在您的情况下,它是调用它的相同函数。如注释中所述 ,没有回调函数, 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)

如果您希望函数仅被有限次调用,则可以添加另一个参数,以跟踪重复次数:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM