Закрытие окна не закрывает программу, даже если функция, вызывающая sys.exit (), привязана к окну close_event.Что может вызвать это? - PullRequest
0 голосов
/ 11 апреля 2011

Программа ниже устанавливает график и отображает синее поле каждый раз, когда пользователь нажимает.Пользователь может сделать больше ящиков, используя всплывающее меню правой кнопкой мыши.Когда я реализовал всплывающее меню (таким образом позволяя несколько синих прямоугольников), программа перестала закрываться при закрытии окна.Я подключил метод 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()

Ответы [ 2 ]

0 голосов
/ 12 апреля 2011

Привязка к событию закрытия и функции события закрытия (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()
0 голосов
/ 11 апреля 2011

Используйте app.Exit() или app.ExitMainLoop() для выхода из основного цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...