2015-08-18 159 views
1

下面的程序提供了一個錯誤消息:Tkinter.self導致無限循環,錯誤

"RuntimeError: maximum recursion depth exceeded while calling a Python object".

原因是self.after

當我創建的計算功能的while true環它工作正常,但我想導致與self.after的循環,這是我讀它應該在的連接來實現與Tkinter的。任何建議表示讚賞。

import Tkinter as tk 
import ttk 
import time 

class App(tk.Tk): 
    def __init__(self): 
     self.root=tk.Tk() 
     self.var1=tk.StringVar() 
     self.i=0 

    def Calculation(self): 
     # complex calculations that last 30 minutes in total 
     self.i+=1 
     self.var1.set(str(self.i)) 
     self.root.update() 
     self.after(100, self.Calculation) 

    def Gui(self): 
     your_label=tk.Label(self.root,textvariable=self.var1).pack() 

A=App() 
A.Gui() 
A.Calculation() 
+0

你想完成什麼?每次計算每100毫秒開始另一次計算,並且這些計算會啓動進一步計算等。這不可能是您想要的。 – saulspatz

+0

這是一個蒙特卡羅模擬。所以每次計算都需要進行很多次,但是由於它們持續了一段時間,每次計算後我都需要在我的gui中進行更新。此外,我希望能夠在計算過程中更改一些參數,理想情況下使用滑塊。 – Nickpick

回答

4

遞歸正在從tk.TK而不是tk.Frame被派生的類App造成的。最重要的是,您的__init__()方法會使用self.root=tk.Tk()語句創建其自己的基類的第二個實例,而不是像它應該那樣調用其基類的__init__()方法。這在這種情況下特別麻煩,因爲tk.TK類的一個實例是Tk的Toplevel小部件,它包含Tcl解釋器,並且通常應該只存在其中的一個。

以下是改變基類的內容,並以適當的方式完成我認爲你正在嘗試做的事情。其中我修正,修改並簡化了其他一些數字,特別是使代碼符合PEP8 style guidelines

import Tkinter as tk 

class App(tk.Frame): 
    def __init__(self, master=None): 
     tk.Frame.__init__(self, master) 
     self.pack() 
     self.var1 = tk.StringVar() 
     self.i = 0 
     tk.Label(self, textvariable=self.var1).pack() 

    def calculation(self): 
     # complex calculations that last 30 minutes in total 
     self.i += 1 
     self.var1.set(str(self.i)) 
#  self.update() # no need, will be automatic as mainloop() runs 
     self.after(100, self.calculation) 

app=App() 
app.calculation() # start calculations 
app.mainloop() # run gui 
+0

註釋「由於Label使用文本變量而自動執行#」不正確。調用更新是不必要的,因爲'mainloop'正在運行,而不是因爲您正在使用'textvariable'。當你的函數結束時,事件循環被重新輸入。 –

+0

@Bryan:感謝您將事情做好。 – martineau

+0

這是我想要的方式,但爲什麼它在self.i + = 1後添加time.sleep(1)時會停止工作? – Nickpick

0

因此,我通過擺脫單獨的Gui函數做了一些重寫,但我認爲這應該做你想做的事情。

import Tkinter as tk 
import ttk 
import time 

class App(): 
    def __init__(self): 
     self.root = tk.Tk() 
     self.i = 0 
     self.label = tk.Label(text=str(self.i)) 
     self.label.pack() 
     self.calculation() 
     self.root.mainloop() 

    def calculation(self): 
     self.i = self.i + 1 
     self.label.configure(text=self.i) 
     self.root.after(100, self.calculation) 

app=App()