[英]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.