2017-02-27 52 views
1

我遇到了用matplotlib寫更新dinamicaly的tkinter應用程序的麻煩。我創建了一個圖並在tkinter窗口中使用它。然後使用tk.after()方法每50ms更新一次繪圖,這在我嘗試使用的其他應用程序中工作正常。但是,在我的應用程序似乎一切都工作到一段時間後(一分鐘左右),我得到一個錯誤:Tkinter,錯誤最大遞歸深度超出

RecursionError:在調用一個Python對象

的代碼是最大遞歸深度超過:

import matplotlib 
#matplotlib.use('TkAgg') 
from numpy import arange, sin, pi 
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg 
# implement the default mpl key bindings 
from matplotlib.backend_bases import key_press_handler 
from matplotlib.figure import Figure 
import sys 
import time 

if sys.version_info[0] < 3: 
    import Tkinter as Tk 
else: 
    import tkinter as Tk 


import numpy as np 
import matplotlib.pyplot as plt 
import math 

class MainWindow(): 

    #---------------- 

    def __init__(self, root): 
     self.index=0 
     self.root=root 
     self.fig, self.ax = plt.subplots() 
     self.line, = self.ax.plot(np.random.randn(100)) 
     #plt.show(block=False) 


     # a tk.DrawingArea 
     self.canvas = FigureCanvasTkAgg(self.fig, master=root) 
     self.canvas.show() 
     self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) 

     self.toolbar = NavigationToolbar2TkAgg(self.canvas, root) 
     self.toolbar.update() 
     self.canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1) 


     self.canvas.mpl_connect('key_press_event', self.on_key_event) 

     self.display = Tk.Label(root, text="") # we need this Label as a variable! 
     self.display.pack() 

     self.button1 = Tk.Button(master=root, text='Quit', command=self._quit) 
     self.button1.pack(side=Tk.BOTTOM) 

     global w 
     w=2*math.pi 


     self.button2 = Tk.Button(master=root, text='Increase frecuency', command=self.button2_event) 
     self.button2.pack(side=Tk.BOTTOM) 

     #A simple clock 
     global miliseconds 
     global t 
     t=time.time() 
     self.update_clock() 
     print('going to the next stop') 
     self.root.mainloop() 


    def on_key_event(event): 
     print('you pressed %s' % event.key) 
     key_press_handler(event, self.canvas, toolbar) 




    def _quit(self): 
     self.root.quit()  # stops mainloop 
     self.root.destroy() # this is necessary on Windows to prevent 
         # Fatal Python Error: PyEval_RestoreThread: NULL tstate 

    def button2_event(self): 

     global t 
     global w 
     w+=2*3.1416 

    def update_clock(self): 

     global t 
     mili=str(math.floor(1000*(t-time.time())))+' ms' 
     t=time.time() 


     now = time.strftime("%H:%M:%S"+'-'+mili) 
     self.display.configure(text=now) 

     N=100 
     y=np.sin(4*math.pi*(np.array(range(N))/N)+t*w) 
     x=range(N) 
     self.line.set_ydata(y) 
     self.line.set_xdata(x) 

     self.ax.relim() 
     self.ax.autoscale() 
     #☺fig.canvas.update() 
     #fig.canvas.flush_events() 

     self.canvas.show() 
     self.canvas.flush_events() 

     self.root.after(50, self.update_clock()) #<------ERROR HERE!------ 


root = Tk.Tk() 
root.wm_title("Embedding in TK") 
MainWindow(root) 
+1

將'self.root.after(50,self.update_clock())'改爲'self.root.after(50,self.update_clock)' – eyllanesc

+0

現在很好用,謝謝! – Victor

+0

我在這裏寫的是迴應,請標記爲正確。 – eyllanesc

回答

3

變化self.root.after(50, self.update_clock())self.root.after(50, self.update_clock)after

after(delay_ms, callback=None, *args)

Registers an alarm callback that is called after a given time.