在调用tkinter中的对象动画时,'Nonetype'对象不可调用

时间:2013-05-20 12:32:17

标签: python animation tkinter

我一直在使用它作为模板:

Blobs Animation

而且我能找到的唯一区别就是他使用了这一行:

from Tkinter import *

而我使用

import Tkinter as Tk

我以为我把Tkinter模块的所有调用都称为Tk。(相当于Blob.py)。我可以运行这个blob动画示例,但我的程序会收到错误:

'Nonetype' object not callable

就行:

allStars[i] = allStars[i]()

从我下面的代码中(这个特定的行在最后一段代码中):

class Star:

    def __init__(self, canvas, xy, delta):

        self.canvas = canvas
        self.delta = delta

        self.id = self.canvas.create_rectangle(
            xy[0],xy[1],
            xy[0]+starSize,xy[1]+starSize,
            fill='white'
            )


    def __call__(self):
        return self.down

    def down(self):

        xy = self.canvas.coords(self.id)
        if xy[1] >= gameScreenHeight:
            x2 = random.randint(1,gameScreenWidth)
            y2 = 0;
            self.canvas.coords(self.id,x2,y2)
        else:
            self.canvas.move(self.id, 0, self.delta)


root = Tk.Tk()
root.title("Stars")
root.resizable(0,0)
TkPlacement = "%dx%d%+d%+d" % (gameScreenWidth, gameScreenHeight, 10*starSize, heightOffset)
root.geometry(TkPlacement)

frame = Tk.Frame(root, bd = 5, relief=Tk.SUNKEN)
frame.pack()

space = Tk.Canvas(frame, width = gameScreenWidth, height = gameScreenHeight, cursor = 'plus')
space.pack()
space.create_rectangle(0,0,gameScreenWidth,gameScreenHeight,fill="black")



allStars = [
    Star(space, (10,30),3),
    Star(space, (15,60),3),
    Star(space, (80,50),5)
    ]

#N = 99;

#for i in range(N):
#   x1 = random.randint(1,gameScreenWidth)
#   y1 = random.randint(1,gameScreenHeight)
#   aStar = Star(space, (x1,y1), 3)
#   allStars.append(aStar)

root.update()

try:
    while 1:
        for i in range(len(allStars)):
            allStars[i] = allStars[i]()
            root.update_idletasks() # redraw
        root.update() # process events
except Tk.TclError:
    pass # to avoid errors when the window is closed

2 个答案:

答案 0 :(得分:2)

在代码的早期,您将allStars[i]设置为函数(self.done)。由于没有显式的return语句,此函数返回None

执行此操作时:

allStars[i] = allStars[i]()

...您正在将allStars[i]的值替换为调用allStars[i]的结果,即None。下一次执行此代码行时,allStars[i]None,因此您会收到该错误。

如果你正在尝试做动画,有更好的方法,而不是让你自己的无限循环运行,因为你已经有一个无限循环运行 - mainloop。例如,您可以使用以下代码删除整个while循环并在代码末尾尝试/ catch块:

def redraw():
    for i in range(len(items)):
        items[i] = items[i]()
    root.after(int(1000/30), redraw) # 30 frames per second

root.after_idle(redraw)
root.mainloop()

答案 1 :(得分:1)

down()返回None(含蓄地);并且第一次通过无限循环,你用它替换了allStars中的所有内容。

allStars[i] = allStars[i]()可能不是你想要的,虽然目前还不清楚你想要用它做什么。