Reputation: 13
You can see the window persists when using QApplicaiton.exit() and then crashes when it tries to restart the second time. Thought it could be a threading issue but it seems to still exist when I try more meticulous methods of closing the matplotlib canvas before exiting.
import sys
import matplotlib
matplotlib.use('Qt5Agg')
from PyQt5 import QtCore, QtGui, QtWidgets
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
class MplCanvas(FigureCanvasQTAgg):
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
super(MplCanvas, self).__init__(fig)
class MainWindow(QtWidgets.QMainWindow):
REBOOT_CODE = -654321
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.sc = MplCanvas(self, width=5, height=4, dpi=100)
self.sc.axes.plot([0, 1, 2, 3, 4], [10, 1, 20, 3, 40])
button = QtWidgets.QPushButton('reload', self)
button.clicked.connect(lambda: self.reloadapp())
layout = QtWidgets.QVBoxLayout()
layout.addWidget(button)
layout.addWidget(self.sc)
# Create a placeholder widget
widget = QtWidgets.QWidget()
widget.setLayout(layout)
self.setCentralWidget(widget)
def reloadapp(self):
self.sc.close_event()
QtWidgets.QApplication.exit( MainWindow.REBOOT_CODE )
if __name__ == '__main__':
exit_code = MainWindow.REBOOT_CODE
while exit_code == MainWindow.REBOOT_CODE:
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()
app = None
Upvotes: 1
Views: 60
Reputation: 244003
The problem is that doing app = None
does not eliminate the QApplication since in Python it is enough that another variable maintains the reference of the object so that it remains alive and that happens with matplotlib that maintains a reference of QApplication. One possible solution is to use sip.delete to delete the C++ object.
Another error is also that you do not assign what app.exec_()
returns to exit_code
which generates an infinite loop. On the other hand it is not necessary to use self.sc.close_event ()
.
from PyQt5 import QtCore, QtGui, QtWidgets, sip
if __name__ == "__main__":
exit_code = MainWindow.REBOOT_CODE
while exit_code == MainWindow.REBOOT_CODE:
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
exit_code = app.exec_()
sip.delete(app)
app = None
Upvotes: 1