为什么被困的 matplotlib 'close_event' 继续杀死我的窗口

问题描述 投票:0回答:1

我正在开展一个更大的项目,其中有几块地块。我可以将绘图图标化,这样就不会弄乱屏幕。我想禁用关闭(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()
python matplotlib event-handling
1个回答
0
投票

发生的情况是,“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

函数,我只是坚持您的示例)

    

© www.soinside.com 2019 - 2024. All rights reserved.