python - 重新启动包含 matplotlib 画布的 PyQt QApplication
问题描述
您可以看到使用 QApplicaiton.exit() 时窗口仍然存在,然后在第二次尝试重新启动时崩溃。认为这可能是一个线程问题,但当我尝试更细致的方法在退出之前关闭 matplotlib 画布时,它似乎仍然存在。
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
解决方案
问题是这样做app = None
并没有消除 QApplication,因为在 Python 中,另一个变量维护对象的引用就足够了,这样它就可以保持活动状态,而 matplotlib 会发生这种情况,它维护 QApplication 的引用。一种可能的解决方案是使用 sip.delete 删除 C++ 对象。
另一个错误也是您没有分配生成无限循环的app.exec_()
返回值。exit_code
另一方面,没有必要使用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
推荐阅读
- javascript - 从 Python 在网页上运行 JS
- javascript - express nodejs POST请求表单输入法
- java - Spring Batch - 连接到 Postgres 数据库的问题
- php - 在 PHP 中运行一个动作函数的一个特定动作
- typescript - 如何忽略 Prettier 格式化的引号
- multithreading - 了解弱内存模型
- html - 嵌套导航栏未在主导航下对齐
- node.js - 在gremlin nodejs中的顶点之间添加边
- python - 如何在Python中迭代开始日期和结束日期之间的所有日子
- android - 单击 RecyclerView 项时,显示一个新的 Activity,其中包含有关该项的信息