2017-03-03 68 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