Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e407926

Browse files
committed
use QMainWindow.closeEvent for close events
The current code uses the QWidget.destroyed signal to emit a close event into matplotlib. This is a very bad idea, as it is a heavy abuse of Qt functionality. When a main window is closed in Qt, it and its children are deleted if the DeleteOnClose flag is set (which we did set). This causes the QWidget.destroyed signal to be called. Setting the DeleteOnClose flag is a very bad idea, since objects should only be deleted by the garbage collector. Soon after, PyQt4 will complain that "the underlying C++ object has been deleted", since the object is alive for python but dead for C++. This patch changes the machinery to use the QMainWindow.closeEvent to emit a close_event, which is what one actually wants.
1 parent 32c302c commit e407926

1 file changed

Lines changed: 7 additions & 15 deletions

File tree

lib/matplotlib/backends/backend_qt4.py

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -208,18 +208,6 @@ def __init__( self, figure ):
208208
w,h = self.get_width_height()
209209
self.resize( w, h )
210210

211-
# JDH: Note the commented out code below does not work as
212-
# expected, because according to Pierre Raybaut, The reason is
213-
# that PyQt fails (silently) to call a method of this object
214-
# just before detroying it. Using a lambda function will work,
215-
# exactly the same as using a function (which is not bound to
216-
# the object to be destroyed).
217-
#
218-
#QtCore.QObject.connect(self, QtCore.SIGNAL('destroyed()'),
219-
# self.close_event)
220-
QtCore.QObject.connect(self, QtCore.SIGNAL('destroyed()'),
221-
lambda: self.close_event())
222-
223211
def __timerEvent(self, event):
224212
# hide until we can test and fix
225213
self.mpl_idle_event(event)
@@ -377,6 +365,10 @@ def idle_draw(*args):
377365
self._idle = True
378366
if d: QtCore.QTimer.singleShot(0, idle_draw)
379367

368+
class MainWindow(QtGui.QMainWindow):
369+
def closeEvent(self, event):
370+
self.emit(QtCore.SIGNAL('closing()'))
371+
380372
class FigureManagerQT( FigureManagerBase ):
381373
"""
382374
Public attributes
@@ -391,8 +383,9 @@ def __init__( self, canvas, num ):
391383
if DEBUG: print('FigureManagerQT.%s' % fn_name())
392384
FigureManagerBase.__init__( self, canvas, num )
393385
self.canvas = canvas
394-
self.window = QtGui.QMainWindow()
395-
self.window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
386+
self.window = MainWindow()
387+
self.window.connect(self.window, QtCore.SIGNAL('closing()'),
388+
canvas.close_event)
396389

397390
self.window.setWindowTitle("Figure %d" % num)
398391
image = os.path.join( matplotlib.rcParams['datapath'],'images','matplotlib.png' )
@@ -619,7 +612,6 @@ def draw_rubberband( self, event, x0, y0, x1, y1 ):
619612
def configure_subplots(self):
620613
self.adj_window = QtGui.QMainWindow()
621614
win = self.adj_window
622-
win.setAttribute(QtCore.Qt.WA_DeleteOnClose)
623615

624616
win.setWindowTitle("Subplot Configuration Tool")
625617
image = os.path.join( matplotlib.rcParams['datapath'],'images','matplotlib.png' )

0 commit comments

Comments
 (0)