Wou*_*ter 5 python pyqt matplotlib pyqt5
所以我最近几天一直在看 stackoverflow 的帖子来解决我遇到的这个问题,并且尝试了一些方法,我仍然无法让我的代码工作。我正在尝试创建一个简单的 Gui,当按下按钮时我可以在其中显示绘图。当我运行主模块时,程序启动。但是当我单击“绘图”按钮时出现错误
RuntimeError:已删除类型为FigureCanvasQTAgg 的包装C/C++ 对象
现在我读到这与删除 C++ 对象有关,而 python 包装器仍然存在,但我似乎无法解决这个问题。我主要关心的是保持 GUI 尽可能模块化,因为我想扩展下面所示的示例代码。有人有好的办法解决我的问题吗?
主要.py
import sys
from PyQt5.QtWidgets import *
from GUI import ui_main
app = QApplication(sys.argv)
ui = ui_main.Ui_MainWindow()
ui.show()
sys.exit(app.exec_())
Run Code Online (Sandbox Code Playgroud)
ui_main.py
from PyQt5.QtWidgets import *
from GUI import frame as fr
class Ui_MainWindow(QMainWindow):
def __init__(self):
super(Ui_MainWindow, self).__init__()
self.central_widget = Ui_CentralWidget()
self.setCentralWidget(self.central_widget)
self.initUI()
def initUI(self):
self.setGeometry(400,300,1280,600)
self.setWindowTitle('Test GUI')
class Ui_CentralWidget(QWidget):
def __init__(self):
super(Ui_CentralWidget, self).__init__()
self.gridLayout = QGridLayout(self)
'''Plot button'''
self.plotButton = QPushButton('Plot')
self.plotButton.setToolTip('Click to create a plot')
self.gridLayout.addWidget(self.plotButton, 1, 0)
'''plotFrame'''
self.plotFrame = fr.PlotFrame()
self.gridLayout.addWidget(self.plotFrame,0,0)
'''Connect button'''
self.plotButton.clicked.connect(fr.example_figure)
Run Code Online (Sandbox Code Playgroud)
框架.py
from PyQt5.QtWidgets import *
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt
class PlotFrame(QFrame):
def __init__(self):
super(PlotFrame, self).__init__()
self.gridLayout = QGridLayout(self)
self.setFrameShape(QFrame.Box)
self.setFrameShadow(QFrame.Raised)
self.setLineWidth(3)
self.figure = plt.figure(figsize=(5, 5))
self.canvas = FigureCanvas(self.figure)
self.gridLayout.addWidget(self.canvas,1,1)
def example_figure():
plt.cla()
ax = PlotFrame().figure.add_subplot(111)
x = [i for i in range(100)]
y = [i ** 0.5 for i in x]
ax.plot(x, y, 'r.-')
ax.set_title('Square root plot')
PlotFrame().canvas.draw()
Run Code Online (Sandbox Code Playgroud)
每次使用时PlotFrame()都会创建一个新对象,在您的情况下,您在 example_figure 中创建 2 个对象,但它们是本地的,因此当执行该函数时它们将被自动删除,从而导致您指出的错误,因为引用丢失了删除时对象而不通知 matplotlib,解决方案是将对象传递给函数。
ui_main.py
# ...
class Ui_CentralWidget(QWidget):
# ...
'''Connect button'''
self.plotButton.clicked.connect(self.on_clicked)
def on_clicked(self):
fr.example_figure(self.plotFrame)
Run Code Online (Sandbox Code Playgroud)
框架.py
# ...
def example_figure(plot_frame):
plt.cla()
ax = plot_frame.figure.add_subplot(111)
x = [i for i in range(100)]
y = [i ** 0.5 for i in x]
ax.plot(x, y, 'r.-')
ax.set_title('Square root plot')
plot_frame.canvas.draw()
Run Code Online (Sandbox Code Playgroud)