2017-03-03 36 views
6

試圖做在Tkinter的簡單的動作:爲什麼Tkinter中的這個形狀更新緩慢?

import tkinter as tk 

class GameApp(object): 
    """ 
    An object for the game window. 

    Attributes: 
     master: Main window tied to the application 
     canvas: The canvas of this window 
    """ 

    def __init__(self, master): 
     """ 
     Initialize the window and canvas of the game. 
     """ 

     self.master = master 
     self.master.title = "Game" 
     self.master.geometry('{}x{}'.format(500, 500)) 

     self.canvas = tk.Canvas(self.master) 
     self.canvas.pack(side="top", fill="both", expand=True) 

     self.start_game() 

    #----------------------------------------------# 


    def start_game(self): 
     """ 
     Actual loading of the game. 
     """ 

     player = Player(self) 

    #----------------------------------------------# 

#----------------------------------------------# 


class Player(object): 
    """ 
    The player of the game. 

    Attributes: 
     color: color of sprite (string) 
     dimensions: dimensions of the sprite (array) 
     canvas: the canvas of this sprite (object) 
     window: the actual game window object (object) 
     momentum: how fast the object is moving (array) 
    """ 


    def __init__(self, window): 

     self.color = "" 
     self.dimensions = [225, 225, 275, 275] 
     self.window = window 
     self.properties() 

    #----------------------------------------------# 

    def properties(self): 
     """ 
     Establish the properties of the player. 
     """ 

     self.color = "blue" 
     self.momentum = [5, 0] 

     self.draw() 
     self.mom_calc() 

    #----------------------------------------------# 

    def draw(self): 
     """ 
     Draw the sprite. 
     """ 

     self.sprite = self.window.canvas.create_rectangle(*self.dimensions, fill=self.color, outline=self.color) 

    #----------------------------------------------# 


    def mom_calc(self): 
     """ 
     Calculate the actual momentum of the thing 
     """ 

     self.window.canvas.move(self.sprite, *self.momentum) 
     self.window.master.after(2, self.mom_calc) 

    #----------------------------------------------# 

#----------------------------------------------# 


root = tk.Tk() 

game_window = GameApp(root) 

哪裏self.momentum是含有2個整數的數組:一個用於x運動,和另一個用於y運動。但是,矩形的實際移動非常緩慢(每秒大約5次移動),而self.window.master.after()時間似乎沒有效果。

以前在另一個tkinter項目中,我設法得到了真正響應的tkinter運動,所以我只是想知道是否有辦法在這種情況下最小化運動更新時間,方法是使用不同風格的OOP,或者完全不同的代碼。

UPDATE:原來在.after()方法中的時間確實很重要,它實際上會疊加到方法的實時上。使用timeit時間調用該方法後,我得到了這樣的輸出:

>>> print(timeit.timeit("(self.window.master.after(2, self.mom_calc))", number=10000, globals={"self":self})) 
0.5395521819053108 

所以我想真正的問題是:爲什麼.after()方法要花這麼長時間?

更新2:在多臺計算機上測試過,任何平臺上的移動仍然很慢。 「

+0

這看起來像方式必要以上代碼來說明probem。請閱讀並遵循以下建議:[如何創建一個最小,完整和可驗證的示例](http://stackoverflow.com/help/mcve),或將您的問題移至http://codereview.stackexchange.com/ –

+1

現在將其最小化。 – Dova

+0

您忘記了「最低,完整和可驗證」的「完整」部分。 –

回答

1

我在使用Python 3.6的Windows 10中至少沒有看到您報告的問題。我按照所示測試了該程序,並在最後添加了root.mainloop()。這沒有顯示矩形,因爲對象已經從畫布上移開得太快而看不到。

所以我修改了這個以在牆壁之間反彈,並添加了一個計數器來打印每秒呼叫數量mom_calc。如果將後超時設置爲20ms,我會按預期每秒獲得50個動作調用。設置爲2ms,因爲在你的文章中,我每秒獲得約425個,所以這裏有一個小小的錯誤,每次調用大約需要2.3或2.4毫秒。這是有點可變的,因爲其他進程可能會佔用這個粒度的一些時間。

這裏是(略)修改後的代碼:

import tkinter as tk 

class GameApp(object): 
    """ 
    An object for the game window. 

    Attributes: 
     master: Main window tied to the application 
     canvas: The canvas of this window 
    """ 

    def __init__(self, master): 
     """ 
     Initialize the window and canvas of the game. 
     """ 

     self.master = master 
     self.master.title = "Game" 
     self.master.geometry('{}x{}'.format(500, 500)) 

     self.canvas = tk.Canvas(self.master, background="white") 
     self.canvas.pack(side="top", fill="both", expand=True) 

     self.start_game() 

    #----------------------------------------------# 


    def start_game(self): 
     """ 
     Actual loading of the game. 
     """ 

     player = Player(self) 

    #----------------------------------------------# 

#----------------------------------------------# 


class Player(object): 
    """ 
    The player of the game. 

    Attributes: 
     color: color of sprite (string) 
     dimensions: dimensions of the sprite (array) 
     canvas: the canvas of this sprite (object) 
     window: the actual game window object (object) 
     momentum: how fast the object is moving (array) 
    """ 


    def __init__(self, window): 

     self.color = "" 
     self.dimensions = [225, 225, 275, 275] 
     self.window = window 
     self.movement = 0 
     self.movement_last = 0 
     self.properties() 

    #----------------------------------------------# 

    def properties(self): 
     """ 
     Establish the properties of the player. 
     """ 

     self.color = "blue" 
     self.momentum = [5, 0] 

     self.draw() 
     self.mom_calc() 
     self.velocity() 

    #----------------------------------------------# 

    def draw(self): 
     """ 
     Draw the sprite. 
     """ 

     self.sprite = self.window.canvas.create_rectangle(*self.dimensions, fill=self.color, outline=self.color) 

    #----------------------------------------------# 


    def mom_calc(self): 
     """ 
     Calculate the actual momentum of the thing 
     """ 

     pos = self.window.canvas.coords(self.sprite) 
     if pos[2] > 500: 
      self.momentum = [-5, 0] 
     elif pos[0] < 2: 
      self.momentum = [5, 0] 

     self.window.canvas.move(self.sprite, *self.momentum) 
     self.window.master.after(2, self.mom_calc) 
     self.movement = self.movement + 1 

    def velocity(self): 
     print(self.movement - self.movement_last) 
     self.movement_last = self.movement 
     self.aid_velocity = self.window.master.after(1000, self.velocity) 

    #----------------------------------------------# 

#----------------------------------------------# 


if __name__ == '__main__': 
    root = tk.Tk() 
    game_window = GameApp(root) 
    root.mainloop() 
+0

'root.mainloop( )'忘記這種感覺就像一個白癡,這似乎是踢球。謝謝。 – Dova