如何正确关闭包含 matplotlib 动画图表的 tk.Toplevel

问题描述

我创建了一个 Tkinter GUI,当按下按钮时,会创建一个 tk.Toplevel。这个 tk.Toplevel 包括一个 matplotlib 动画图表,它作为一个 tk 小部件插入。 我的问题是,当我关闭 tk.Toplevel 并按下按钮创建另一个 tk.Toplevel 时,除了所需的 tk.Toplevel 之外,还会生成一个 matplotlib 图。 我曾尝试使用 'WM_DELETE_WINDOW' tk.Toplevel 关闭协议并执行:

plt.close()
tk.Toplevel.destroy()

但是这样做,主 GUI 和 tk.Toplevel 都关闭了。

接下来的代码行简化了我的程序:

import tkinter as tk
import matplotlib
import matplotlib.figure as mf
import matplotlib.pyplot as plt
import matplotlib.animation as ani
from matplotlib.animation import FuncAnimation
from matplotlib.backends.backend_tkagg import figureCanvasTkAgg
import numpy as np

class SampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        container = tk.Frame(self)
        container.pack()
        frame = MAININTERFACE(parent=container,controller=self)
        frame.grid(row=0,column=0,sticky="nsew")
    def graph(self):
        grafica1=GRAPHICATION(controller=self)
        grafica1.Graph()

class MAININTERFACE(tk.Frame):
    def __init__(self,parent,controller):
        tk.Frame.__init__(self,parent)
        self.controller = controller
        self.button=tk.Button(self,text='GRAPH',command=lambda: self.controller.graph())
        self.button.pack(pady=20)

class GRAPHICATION(tk.Frame):
    def __init__(self,controller):
        tk.Frame.__init__(self)
        self.controller=controller
        self.x=[]
        self.y=[]
    def animation_frame(self,i):
        if i==0.0:
            self.time=0
            self.energy=0
        else:
            self.time=self.time+1
            self.energy=self.energy+1
        self.x.append(self.time)
        self.y.append(self.energy)
        self.line.set_data(self.x,self.y)
        self.ax.axis([0,10,10])

    def Graph(self):
        self.graphtoplevel=tk.Toplevel(self.controller)
        self.graphtoplevel.title('Toplevel')
        self.fig,self.ax = plt.subplots()
        self.graph=figureCanvasTkAgg(self.fig,self.graphtoplevel)
        self.image=self.graph.get_tk_widget()
        plt.ion()
        self.line,= self.ax.plot(self.x,self.y)
        self.image.grid(row=0,sticky='nsew')
        self.animation=FuncAnimation(self.fig,func=self.animation_frame,frames=np.arange(0,11,1),interval=500,repeat=False)

if __name__ == "__main__":
    app = SampleApp()
    app.geometry('500x200')
    app.title('MAIN GUI')
    app.mainloop()

希望我的问题被理解。谢谢。

解决方法

这个问题可以通过在关闭tk.Toplevel时删除plt.ion()或者做plt.ioff()来解决。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...