2014-04-09 61 views
2

我的目標是實例化一個名爲箭頭的類,所以我可以有更多的箭頭,然後只是1.我想從座標200,200開始,並且希望將x增加15每100毫秒。但是,當我嘗試執行此代碼它給我以下錯誤:調用Python對象時超出最大遞歸深度

File "game.py", line 25, in moveArrow 
    self.after(100, self.moveArrow(arrow, xCoord+15, yCoord)) #repeat, changing x 
    File "game.py", line 24, in moveArrow 
    arrow.place(x = xCoord, y = yCoord) #replace with new x,y 
    File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1860, in place_configure 
    + self._options(cnf, kw)) 
    File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1055, in _options 
    elif isinstance(v, (tuple, list)): 
RuntimeError: maximum recursion depth exceeded while calling a Python object 

「文件 「game.py」 25行,在移動箭頭self.after(100,self.moveArrow(箭頭,XCOORD + 15,yCoord))#repeat,改變x「也經常重複。

from Tkinter import * 
from random import randint 
from PIL import ImageTk, Image 

class App(Frame): 
     def __init__(self, master=None): 
       Frame.__init__(self, master, height=400, width=400) 
       self.master = master 
       self.master.bind('<Shift_L>', self.createArrow) 
     def createArrow(self, event): 
       self.arrow = Arrow(self) 
       self.arrow.moveArrow(self.arrow, 200, 200) 

class Arrow(Frame): 
     def __init__(self, master): 
       Frame.__init__(self, master) 
       self.arrowImage = ImageTk.PhotoImage(Image.open("arrow.gif")) 
       Label(self, image=self.arrowImage).pack() 
     def moveArrow(self, arrow, xCoord, yCoord): 
       arrow.place_forget() 
       arrow.place(x = xCoord, y = yCoord) 
       self.after(100, self.moveArrow(arrow, xCoord+15, yCoord)) 

root = Tk() 
root.title("Mein erstes Spiel") 
app = App(master=root).pack() 
root.mainloop() 

回答

5

其他的答案是這個問題是此行的源正確:

self.after(100, self.moveArrow(arrow, xCoord+15, yCoord)) 

但答案是Tkinter的具體:

看看該文檔的after方法怎麼看正確實施這種方法。像調用普通函數一樣調用它就能做到這一點,並在控制流達到該函數調用時將程序放入無限循環。當您使用after,你有兩個選擇:

路過的時候ARG,然後回調,那麼回調ARGS:

self.after(100, self.moveArrow, arrow, xCoord+15, yCoord) 

或者,使用lambda表達式來保存函數調用:

self.after(100, lambda: self.moveArrow(arrow, xCoord+15, yCoord)) 
+0

http://effbot.org/tkinterbook/photoimage.htm < - 如果你對圖像有問題,特別是關於如何保留參考底部的註釋,請看看。我只用一個文本標籤進行測試。 – atlasologist

+2

這裏有很多很好的信息:http://effbot.org/tkinterbook/tkinter-index.htm ...除此之外,只是做東西,你會發現它 – atlasologist

1

您在致電self.moveArrow(arrow, xCoord+15, yCoord)moveArrow()方法。

所以你有一個無限的遞歸,沒有break在任何階段。 如果你想了解如何構建Python遞歸方法,你可以閱讀here

如果你想創建一些簡單的運動效果,那麼就去做一個循環讓說,你得到X + 200和移動箭頭y + 200會產生一個簡單的for循環,並延遲移動箭頭。

僞代碼示例:

def moveArrow(....) 
    loop: 
     x += 10 
     y += 10 
     change_arrow_place(...) 
+1

@Ibrahim Apachi你可以看到我的更新。 –

+0

這絕對是在tkinter中做動畫的錯誤方法。你永遠不應該在GUI中調用'sleep'。 –

+0

@Bryan Oakley你是對的,因爲睡眠會凍結整個gui,這只是例如。 –

0

線,其創建的問題是

self.after(100, self.moveArrow(arrow, xCoord+15, yCoord))x 

moveArrow因爲沒有斷點條件。當我們在編程語言中使用遞歸時,遞歸需要break條件,它不會調用更多的相同函數。

例如:質數在遞歸

int isPrime(int num,int i){ 

    if(i==1){ 
     return 1; 
    }else{ 
     if(num%i==0) 
     return 0; 
     else 
     isPrime(num,i-1); 
    } 
} 

在上面的代碼中斷點條件,在這些條件2和if (i==1)if(num%i==0)它不會調用isPrime功能和遞歸將終止在那裏。

請添加休息條件並重新運行。

+0

你是正確的線,你是不正確的解釋。 –

+0

如果你能解釋我什麼是不正確的解釋,那麼它會明確我的看法:) – Nilesh

+1

正確的解釋是在這個答案:http://stackoverflow.com/a/22959959/7432。這個問題與需要「休息」條件無關。問題與'後'如何被調用有關。 –

相關問題