窗口关闭不会关闭程序,即使调用绑定到窗口 close_event 的 sys.exit() 的函数也是如此。什么可能导致这种情况?

发布于 2024-10-31 08:15:32 字数 6451 浏览 1 评论 0原文

下面的程序设置一个图表,并在用户每次单击时显示一个蓝色框。 用户可以使用右键单击弹出菜单来制作更多框。当我实现弹出菜单(从而允许多个蓝色框)时,程序在窗口关闭时停止关闭。我将 deleteAll() 方法连接到画布以强制 sys.exit() 关闭,但程序仍然保持打开状态。我做错了什么?

#**************************************************************************#
# Set up a graph. A click creates a blue box. More blue boxes can be made
# by choosing "Make a new box" from right/click menu.
#**************************************************************************#

import wx
import matplotlib
matplotlib.use('WX')
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanv
from pylab import *

#**************************************************************************#
class MainCanvas(wx.Frame):
    """ Class to set up graph """
    def __init__(self):
        wx.Frame.__init__(self,None,-1, 'Make Blue Boxes',size=(550,350))

    #**********************************************************************#
    def setupGraph(self):
        """ Set up window and graph """
        self.definePlot() 
        self.canvas = FigCanv(self, -1, self.figure)
        self.setSizer() 

    #**********************************************************************#
    def definePlot(self):
        """ Define attributes of graph """
        self.SetBackgroundColour(wx.NamedColor("WHITE"))
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)

    #**********************************************************************#
    def setSizer(self):
        """ Set the size of the graph """
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

#**************************************************************************#
class BlueBox(MainCanvas):
    """ Class to set up BlueBox """
    def __init__(self):
        MainCanvas.__init__(self)

    #**********************************************************************#
    def setupBlueBox(self):
        """ Blue box set up """
        self.blueBox = patches.Rectangle((0, 0), 0.05, 0.05,  
                fc = "Blue", visible = False, zorder = 3)
        # Set zorder so new boxes are in front of old
        if len(self.listDT)>1: 
            oldz = self.listDT[len(self.listDT)-2].blueBox.get_zorder() + 3
            self.listDT[len(self.listDT)-1].blueBox.set_zorder(oldz)

        self.axes.add_patch(self.blueBox)


    #**********************************************************************#      
    def onPick(self, event):
        """ Behavior when graph is clicked """
        # Refresh BlueBox position and coordinate text
        self.refreshBlueBox(event)    
        # Set the current BlueBox visible
        self.listDT[len(self.listDT)-1].setVisible()

    #**********************************************************************#
    def refreshBlueBox(self, event):
        """ Blue box refresh    """
        # Center the BlueBox (Point Box) over the mouse click location
        self.blueBox.set_x(event.xdata - .5 * self.blueBox.get_width())
        self.blueBox.set_y(event.ydata - .5 * self.blueBox.get_height())

    #**********************************************************************#
    def setVisible(self):
        """ Make BlueBox visible and refresh canvas """
        self.blueBox.set_visible(True)
        self.figure.canvas.draw()

    #**********************************************************************#
    def setGraphAttributes(self, axes, figure, listDT):
        """ Tell each BlueBox about the graph attributes it needs """
        self.axes = axes
        self.figure = figure
        self.listDT = listDT


#**************************************************************************#
class MyPopupMenu(BlueBox):
    """ Class to handle right clicks """
    def __init__(self):
        BlueBox.__init__(self)

    #**********************************************************************#
    def setup(self):
        """ Set up graph and BlueBox """
        self.setupGraph()
        # Bind right clicks to open the popup menu
        self.canvas.Bind(wx.EVT_RIGHT_DOWN,
                self.createPopupMenu)

        # Create lists for BlueBoxs and binding IDs
        self.listDT = []
        self.listBID = []

        self.popupCreateNew = wx.NewId()
        self.menu = wx.Menu()
        self.cn = self.menu.Append(self.popupCreateNew, 
                "Make a new box")
        self.Bind(wx.EVT_MENU, self.createNew, self.cn)

        # Make the first BlueBox
        self.newBox()

        # Connect close events to delete everything
        self.figure.canvas.mpl_connect('close_event', self.deleteAll) 

    #**********************************************************************#
    def deleteAll(self, event):
        """ Close out of the program cleanly """
        self.Destroy()
        sys.exit(0)

    #**********************************************************************#
    def createPopupMenu(self, event):
        """ Create all parts of the right-click popup menu """
        self.PopupMenu(self.menu)

    #**********************************************************************#
    def newBox(self):
        """ Make a new BlueBox """
        self.listDT.append(BlueBox())
        self.listDT[len(self.listDT)-1].setGraphAttributes(self.axes, 
                self.figure, self.listDT)
        self.listDT[len(self.listDT)-1].setupBlueBox()
        self.listBID.append(self.figure.canvas.mpl_connect('button_press_event', 
                self.listDT[len(self.listDT)-1].onPick)) 

    #**********************************************************************#
    def createNew(self, event):
        """ Create a new BlueBox """
        event.Skip()
        self.newBox()
        if len(self.listBID) > 1: 
            self.figure.canvas.mpl_disconnect(self.listBID[len(self.listBID)-2])


#**************************************************************************#
class app(wx.App):
    """ Create and show all """
    def OnInit(self):
        self.mpm = MyPopupMenu()
        self.mpm.setup()
        self.frame = self.mpm.Show()        
        return True


#**************************************************************************#
# Run the program
#**************************************************************************#
app = app(0)
app.MainLoop()

The program below sets up a graph and displays a blue box each time the user clicks.
A user can make more boxes using the right-click popup menu. When I implemented the popup menu (thus allowing multiple blue boxes) the program stopped closing on the window close. I connected a deleteAll() method to the canvas to force a sys.exit() on close, but the program still stays open. What am I doing wrong?

#**************************************************************************#
# Set up a graph. A click creates a blue box. More blue boxes can be made
# by choosing "Make a new box" from right/click menu.
#**************************************************************************#

import wx
import matplotlib
matplotlib.use('WX')
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanv
from pylab import *

#**************************************************************************#
class MainCanvas(wx.Frame):
    """ Class to set up graph """
    def __init__(self):
        wx.Frame.__init__(self,None,-1, 'Make Blue Boxes',size=(550,350))

    #**********************************************************************#
    def setupGraph(self):
        """ Set up window and graph """
        self.definePlot() 
        self.canvas = FigCanv(self, -1, self.figure)
        self.setSizer() 

    #**********************************************************************#
    def definePlot(self):
        """ Define attributes of graph """
        self.SetBackgroundColour(wx.NamedColor("WHITE"))
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)

    #**********************************************************************#
    def setSizer(self):
        """ Set the size of the graph """
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

#**************************************************************************#
class BlueBox(MainCanvas):
    """ Class to set up BlueBox """
    def __init__(self):
        MainCanvas.__init__(self)

    #**********************************************************************#
    def setupBlueBox(self):
        """ Blue box set up """
        self.blueBox = patches.Rectangle((0, 0), 0.05, 0.05,  
                fc = "Blue", visible = False, zorder = 3)
        # Set zorder so new boxes are in front of old
        if len(self.listDT)>1: 
            oldz = self.listDT[len(self.listDT)-2].blueBox.get_zorder() + 3
            self.listDT[len(self.listDT)-1].blueBox.set_zorder(oldz)

        self.axes.add_patch(self.blueBox)


    #**********************************************************************#      
    def onPick(self, event):
        """ Behavior when graph is clicked """
        # Refresh BlueBox position and coordinate text
        self.refreshBlueBox(event)    
        # Set the current BlueBox visible
        self.listDT[len(self.listDT)-1].setVisible()

    #**********************************************************************#
    def refreshBlueBox(self, event):
        """ Blue box refresh    """
        # Center the BlueBox (Point Box) over the mouse click location
        self.blueBox.set_x(event.xdata - .5 * self.blueBox.get_width())
        self.blueBox.set_y(event.ydata - .5 * self.blueBox.get_height())

    #**********************************************************************#
    def setVisible(self):
        """ Make BlueBox visible and refresh canvas """
        self.blueBox.set_visible(True)
        self.figure.canvas.draw()

    #**********************************************************************#
    def setGraphAttributes(self, axes, figure, listDT):
        """ Tell each BlueBox about the graph attributes it needs """
        self.axes = axes
        self.figure = figure
        self.listDT = listDT


#**************************************************************************#
class MyPopupMenu(BlueBox):
    """ Class to handle right clicks """
    def __init__(self):
        BlueBox.__init__(self)

    #**********************************************************************#
    def setup(self):
        """ Set up graph and BlueBox """
        self.setupGraph()
        # Bind right clicks to open the popup menu
        self.canvas.Bind(wx.EVT_RIGHT_DOWN,
                self.createPopupMenu)

        # Create lists for BlueBoxs and binding IDs
        self.listDT = []
        self.listBID = []

        self.popupCreateNew = wx.NewId()
        self.menu = wx.Menu()
        self.cn = self.menu.Append(self.popupCreateNew, 
                "Make a new box")
        self.Bind(wx.EVT_MENU, self.createNew, self.cn)

        # Make the first BlueBox
        self.newBox()

        # Connect close events to delete everything
        self.figure.canvas.mpl_connect('close_event', self.deleteAll) 

    #**********************************************************************#
    def deleteAll(self, event):
        """ Close out of the program cleanly """
        self.Destroy()
        sys.exit(0)

    #**********************************************************************#
    def createPopupMenu(self, event):
        """ Create all parts of the right-click popup menu """
        self.PopupMenu(self.menu)

    #**********************************************************************#
    def newBox(self):
        """ Make a new BlueBox """
        self.listDT.append(BlueBox())
        self.listDT[len(self.listDT)-1].setGraphAttributes(self.axes, 
                self.figure, self.listDT)
        self.listDT[len(self.listDT)-1].setupBlueBox()
        self.listBID.append(self.figure.canvas.mpl_connect('button_press_event', 
                self.listDT[len(self.listDT)-1].onPick)) 

    #**********************************************************************#
    def createNew(self, event):
        """ Create a new BlueBox """
        event.Skip()
        self.newBox()
        if len(self.listBID) > 1: 
            self.figure.canvas.mpl_disconnect(self.listBID[len(self.listBID)-2])


#**************************************************************************#
class app(wx.App):
    """ Create and show all """
    def OnInit(self):
        self.mpm = MyPopupMenu()
        self.mpm.setup()
        self.frame = self.mpm.Show()        
        return True


#**************************************************************************#
# Run the program
#**************************************************************************#
app = app(0)
app.MainLoop()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦开始←不甜 2024-11-07 08:15:32

使用 app.Exit()app.ExitMainLoop() 退出主循环。

Use app.Exit() or app.ExitMainLoop() to exit the main loop instead.

柒七 2024-11-07 08:15:32

到关闭事件和关闭事件函数 (deleteAll()) 的绑定需要位于创建图形的类中。

工作代码如下。

#**************************************************************************#
# Set up a graph. A click creates a blue box. More blue boxes can be made
# by choosing "Make a new box" from right/click menu.
#**************************************************************************#

import wx
import matplotlib
matplotlib.use('WX')
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanv
from pylab import *

#**************************************************************************#
class MainCanvas(wx.Frame):
    """ Class to set up graph """
    def __init__(self):
        wx.Frame.__init__(self,None,-1, 'Make Blue Boxes',size=(550,350))
        self.Bind(wx.EVT_CLOSE, self.deleteAll)

    #**********************************************************************#
    def deleteAll(self,event):
        sys.exit()

    #**********************************************************************#
    def setupGraph(self):
        """ Set up window and graph """
        self.definePlot() 
        self.canvas = FigCanv(self, -1, self.figure)
        self.setSizer() 

    #**********************************************************************#
    def definePlot(self):
        """ Define attributes of graph """
        self.SetBackgroundColour(wx.NamedColor("WHITE"))
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)

    #**********************************************************************#
    def setSizer(self):
        """ Set the size of the graph """
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

#**************************************************************************#
class BlueBox(MainCanvas):
    """ Class to set up BlueBox """
    def __init__(self):
        MainCanvas.__init__(self)

    #**********************************************************************#
    def setupBlueBox(self):
        """ Blue box set up """
        self.blueBox = patches.Rectangle((0, 0), 0.05, 0.05,  
                fc = "Blue", visible = False, zorder = 3)
        # Set zorder so new boxes are in front of old
        if len(self.listDT)>1: 
            oldz = self.listDT[len(self.listDT)-2].blueBox.get_zorder() + 3
            self.listDT[len(self.listDT)-1].blueBox.set_zorder(oldz)

        self.axes.add_patch(self.blueBox)


    #**********************************************************************#      
    def onPick(self, event):
        """ Behavior when graph is clicked """
        # Refresh BlueBox position and coordinate text
        self.refreshBlueBox(event)    
        # Set the current BlueBox visible
        self.listDT[len(self.listDT)-1].setVisible()

    #**********************************************************************#
    def refreshBlueBox(self, event):
        """ Blue box refresh    """
        # Center the BlueBox (Point Box) over the mouse click location
        self.blueBox.set_x(event.xdata - .5 * self.blueBox.get_width())
        self.blueBox.set_y(event.ydata - .5 * self.blueBox.get_height())

    #**********************************************************************#
    def setVisible(self):
        """ Make BlueBox visible and refresh canvas """
        self.blueBox.set_visible(True)
        self.figure.canvas.draw()

    #**********************************************************************#
    def setGraphAttributes(self, axes, figure, listDT):
        """ Tell each BlueBox about the graph attributes it needs """
        self.axes = axes
        self.figure = figure
        self.listDT = listDT


#**************************************************************************#
class MyPopupMenu(BlueBox):
    """ Class to handle right clicks """
    def __init__(self):
        BlueBox.__init__(self)

    #**********************************************************************#
    def setup(self):
        """ Set up graph and BlueBox """
        self.setupGraph()
        # Bind right clicks to open the popup menu
        self.canvas.Bind(wx.EVT_RIGHT_DOWN,
                self.createPopupMenu)

        # Create lists for BlueBoxs and binding IDs
        self.listDT = []
        self.listBID = []

        self.popupCreateNew = wx.NewId()
        self.menu = wx.Menu()
        self.cn = self.menu.Append(self.popupCreateNew, 
                "Make a new box")
        self.Bind(wx.EVT_MENU, self.createNew, self.cn)

        # Make the first BlueBox
        self.newBox()


    #**********************************************************************#
    def createPopupMenu(self, event):
        """ Create all parts of the right-click popup menu """
        self.PopupMenu(self.menu)

    #**********************************************************************#
    def newBox(self):
        """ Make a new BlueBox """
        self.listDT.append(BlueBox())
        self.listDT[len(self.listDT)-1].setGraphAttributes(self.axes, 
                self.figure, self.listDT)
        self.listDT[len(self.listDT)-1].setupBlueBox()
        self.listBID.append(self.figure.canvas.mpl_connect('button_press_event', 
                self.listDT[len(self.listDT)-1].onPick)) 

    #**********************************************************************#
    def createNew(self, event):
        """ Create a new BlueBox """
        event.Skip()
        self.newBox()
        if len(self.listBID) > 1: 
            self.figure.canvas.mpl_disconnect(self.listBID[len(self.listBID)-2])


#**************************************************************************#
class app(wx.App):
    """ Create and show all """
    def OnInit(self):
        self.mpm = MyPopupMenu()
        self.mpm.setup()
        self.frame = self.mpm.Show()        
        return True


#**************************************************************************#
# Run the program
#**************************************************************************#
app = app(0)
app.MainLoop()

The binding to the close event and the close event function (deleteAll()) needed to be in the class where the graph was being created.

The working code is below.

#**************************************************************************#
# Set up a graph. A click creates a blue box. More blue boxes can be made
# by choosing "Make a new box" from right/click menu.
#**************************************************************************#

import wx
import matplotlib
matplotlib.use('WX')
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.figure import Figure
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigCanv
from pylab import *

#**************************************************************************#
class MainCanvas(wx.Frame):
    """ Class to set up graph """
    def __init__(self):
        wx.Frame.__init__(self,None,-1, 'Make Blue Boxes',size=(550,350))
        self.Bind(wx.EVT_CLOSE, self.deleteAll)

    #**********************************************************************#
    def deleteAll(self,event):
        sys.exit()

    #**********************************************************************#
    def setupGraph(self):
        """ Set up window and graph """
        self.definePlot() 
        self.canvas = FigCanv(self, -1, self.figure)
        self.setSizer() 

    #**********************************************************************#
    def definePlot(self):
        """ Define attributes of graph """
        self.SetBackgroundColour(wx.NamedColor("WHITE"))
        self.figure = Figure()
        self.axes = self.figure.add_subplot(111)

    #**********************************************************************#
    def setSizer(self):
        """ Set the size of the graph """
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)
        self.Fit()

#**************************************************************************#
class BlueBox(MainCanvas):
    """ Class to set up BlueBox """
    def __init__(self):
        MainCanvas.__init__(self)

    #**********************************************************************#
    def setupBlueBox(self):
        """ Blue box set up """
        self.blueBox = patches.Rectangle((0, 0), 0.05, 0.05,  
                fc = "Blue", visible = False, zorder = 3)
        # Set zorder so new boxes are in front of old
        if len(self.listDT)>1: 
            oldz = self.listDT[len(self.listDT)-2].blueBox.get_zorder() + 3
            self.listDT[len(self.listDT)-1].blueBox.set_zorder(oldz)

        self.axes.add_patch(self.blueBox)


    #**********************************************************************#      
    def onPick(self, event):
        """ Behavior when graph is clicked """
        # Refresh BlueBox position and coordinate text
        self.refreshBlueBox(event)    
        # Set the current BlueBox visible
        self.listDT[len(self.listDT)-1].setVisible()

    #**********************************************************************#
    def refreshBlueBox(self, event):
        """ Blue box refresh    """
        # Center the BlueBox (Point Box) over the mouse click location
        self.blueBox.set_x(event.xdata - .5 * self.blueBox.get_width())
        self.blueBox.set_y(event.ydata - .5 * self.blueBox.get_height())

    #**********************************************************************#
    def setVisible(self):
        """ Make BlueBox visible and refresh canvas """
        self.blueBox.set_visible(True)
        self.figure.canvas.draw()

    #**********************************************************************#
    def setGraphAttributes(self, axes, figure, listDT):
        """ Tell each BlueBox about the graph attributes it needs """
        self.axes = axes
        self.figure = figure
        self.listDT = listDT


#**************************************************************************#
class MyPopupMenu(BlueBox):
    """ Class to handle right clicks """
    def __init__(self):
        BlueBox.__init__(self)

    #**********************************************************************#
    def setup(self):
        """ Set up graph and BlueBox """
        self.setupGraph()
        # Bind right clicks to open the popup menu
        self.canvas.Bind(wx.EVT_RIGHT_DOWN,
                self.createPopupMenu)

        # Create lists for BlueBoxs and binding IDs
        self.listDT = []
        self.listBID = []

        self.popupCreateNew = wx.NewId()
        self.menu = wx.Menu()
        self.cn = self.menu.Append(self.popupCreateNew, 
                "Make a new box")
        self.Bind(wx.EVT_MENU, self.createNew, self.cn)

        # Make the first BlueBox
        self.newBox()


    #**********************************************************************#
    def createPopupMenu(self, event):
        """ Create all parts of the right-click popup menu """
        self.PopupMenu(self.menu)

    #**********************************************************************#
    def newBox(self):
        """ Make a new BlueBox """
        self.listDT.append(BlueBox())
        self.listDT[len(self.listDT)-1].setGraphAttributes(self.axes, 
                self.figure, self.listDT)
        self.listDT[len(self.listDT)-1].setupBlueBox()
        self.listBID.append(self.figure.canvas.mpl_connect('button_press_event', 
                self.listDT[len(self.listDT)-1].onPick)) 

    #**********************************************************************#
    def createNew(self, event):
        """ Create a new BlueBox """
        event.Skip()
        self.newBox()
        if len(self.listBID) > 1: 
            self.figure.canvas.mpl_disconnect(self.listBID[len(self.listBID)-2])


#**************************************************************************#
class app(wx.App):
    """ Create and show all """
    def OnInit(self):
        self.mpm = MyPopupMenu()
        self.mpm.setup()
        self.frame = self.mpm.Show()        
        return True


#**************************************************************************#
# Run the program
#**************************************************************************#
app = app(0)
app.MainLoop()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文