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