我正在开展一个更大的项目,其中有几块地块。我可以将绘图图标化,这样就不会弄乱屏幕。我想禁用关闭(X),而是让它只是图标化绘图。使用 mpl_connect() 我期望捕获事件并处理“close_event”,如果它结束,但事实并非如此。在所附代码中,如果您显示两个图并用 (X) 关闭其中一个图。它图标化了一个,但杀死了被点击的那个。
import tkinter as tk
import numpy as np
import matplotlib.pyplot as plt
import sys
# make some data
x = np.linspace(0,1,100)
sinx = np.sin(8.0*np.pi*x)
cosx = np.cos(8.0*np.pi*x)
def showPlot1():
plotMng1.window.deiconify()
def hidePlot1():
plotMng1.window.iconify()
def showPlot2():
plotMng2.window.deiconify()
def hidePlot2():
plotMng2.window.iconify()
def handle_close(event):
# Prevent the default close behavior
print("my handler called by {}".format(event))
plotMng1.window.iconify()
plotMng2.window.iconify()
def quitAll():
plt.close()
root.destroy()
sys.exit()
# make an instance of Tk
root = tk.Tk()
plt.ion()
# generate a plot
fig1, axs1 = plt.subplots()
fig1.canvas.mpl_connect('close_event', handle_close) # catch the close event
axs1.plot(x,sinx,'-', label="sin")
axs1.set_xlim(0,1)
axs1.set_ylim(-1,1)
axs1.legend(loc="upper right")
plotMng1 = plt.get_current_fig_manager()
plotMng1.window.iconify()
# generate another plot
fig2, axs2 = plt.subplots()
fig2.canvas.mpl_connect('close_event', handle_close) # catch the close event
axs2.plot(x,cosx,'-', label="cos")
axs2.set_xlim(0,1)
axs2.set_ylim(-1,1)
axs2.legend(loc="upper right")
plotMng2 = plt.get_current_fig_manager()
plotMng2.window.iconify()
tk.Button(root, text="Show 1",padx = 20, command=showPlot1).pack()
tk.Button(root, text="Hide 1",padx = 20, command=hidePlot1).pack()
tk.Button(root, text="Show 2",padx = 20, command=showPlot2).pack()
tk.Button(root, text="Hide 2",padx = 20, command=hidePlot2).pack()
tk.Button(root, text="Quit",padx = 20, command=quitAll).pack()
root.protocol("WM_DELETE_WINDOW", quitAll)
root.mainloop()
发生的情况是,“close_event”事件在窗口实际关闭之后被调用,因此当您尝试图标化窗口时,它已经关闭了。
mpl_connect
是一个很好的尝试,但不幸的是你不会实现你想做的事情。
您想要做的是与Fig_manager而不是画布进行交互,并对实际关闭窗口之前触发的事件"WM_DELETE_WINDOW"
做出反应。
因此,绘图定义应如下所示:fig1, axs1 = plt.subplots()
axs1.plot(x, sinx, '-', label="sin")
axs1.set_xlim(0, 1)
axs1.set_ylim(-1, 1)
axs1.legend(loc="upper right")
plotMng1= plt.get_current_fig_manager()
#Add the following line in every plot definition
plotMng1.window.protocol("WM_DELETE_WINDOW", handle_close)
plotMng1.window.iconify()
并且您必须随后调整
handle_close
函数(因为它现在不接受任何参数):
def handle_close():
plotMng1.window.iconify()
plotMng2.window.iconify()
(您也可以根据您想要的行为为每个图定义一个
handle_close
函数,我只是坚持您的示例)