Hi,

Some Spyder users have reported a critical bug occuring with matplotlib 
0.99's Qt4 backend and PyQt4 v4.6 (e.g. in Ubuntu Karmic).


Here is the traceback after calling 'plot([])', closing figure and 
calling again 'plot([])' (e.g. in an IPython session with options 
--pylab and --q4thread):

Traceback (most recent call last):
  File "/home/rick/Temp/untitled0.py", line 9, in <module>
    show()
  File "/usr/lib/pymodules/python2.6/matplotlib/backends/backend_qt4.py",
line 63, in show
    manager.window.show()
RuntimeError: underlying C/C++ object has been deleted


I found out that the 'destroyed()' signal (connected in class FigureManagerQT) 
is never emitted when figure is closed.
As a consequence, SIP is not very happy when trying to draw a deleted object...

I made the following changes to make it work:

# New class to clarify code in FigureManagerQT
class FigureWindow(QtGui.QMainWindow):
    def __init__(self, num, canvas, close_callback):
        super(FigureWindow, self).__init__()
        self.close_callback = close_callback
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setWindowTitle("Figure %d" % num)
        image = os.path.join(matplotlib.rcParams['datapath'],
                             'images', 'matplotlib.png')
        self.setWindowIcon(QtGui.QIcon(image))
        self._destroying = False
        self.setCentralWidget(canvas)
        if matplotlib.is_interactive():
            self.show()
        
    def closeEvent(self, event):
        super(FigureWindow, self).closeEvent(event)
        self.close_callback()

class FigureManagerQT( FigureManagerBase ):
    """
    Public attributes

    canvas      : The FigureCanvas instance
    num         : The Figure number
    toolbar     : The qt.QToolBar
    window      : The qt.QMainWindow
    """

    def __init__( self, canvas, num ):
        if DEBUG: print 'FigureManagerQT.%s' % fn_name()
        FigureManagerBase.__init__( self, canvas, num )
        self.canvas = canvas

        # Give the keyboard focus to the figure instead of the manager
        self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus )
        self.canvas.setFocus()

        self.window = FigureWindow(num, self.canvas, self._widgetclosed)
        self.toolbar = self._get_toolbar(self.canvas, self.window)
        self.window.addToolBar(self.toolbar)
        QtCore.QObject.connect(self.toolbar, QtCore.SIGNAL("message"),
                               self.window.statusBar().showMessage)
# [...]

And we may now remove the "QtCore.QObject.disconnect" for the no longer 
existing signal 'destroyed()' in method 'FigureManagerQT.
destroy'.

HTH

Cheers,
Pierre


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-devel

Reply via email to