2015-08-18 143 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()