簡體   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