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