【问题标题】:PyQt5: RuntimeError: wrapped C/C++ object of type FigureCanvasQTAgg has been deletedPyQt5:RuntimeError:类型为 FigureCanvasQTAgg 的包装 C/C++ 对象已被删除
【发布时间】:2019-06-05 01:37:03
【问题描述】:

因此,过去几天我一直在查看 stackoverflow 帖子以解决我遇到的这个问题,并且尝试了几件事,但我仍然无法让我的代码正常工作。我正在尝试创建一个简单的 Gui,我可以在按下按钮时显示一个情节。当我运行我的主模块时,程序启动。但是当我点击我的“情节”按钮时,我得到了错误

RuntimeError: FigureCanvasQTAgg 类型的包装 C/C++ 对象已被删除

现在我读到这与被删除的 C++ 对象有关,而 python 包装器仍然存在,但我似乎无法解决这个问题。我主要关心的是保持 GUI 尽可能模块化,因为我想扩展下面显示的示例代码。有人对我的问题有好的解决方案吗?

main.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_())

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)

frame.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()

【问题讨论】:

    标签: python matplotlib pyqt pyqt5


    【解决方案1】:

    每次您使用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)
    

    frame.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()
    

    【讨论】:

      猜你喜欢
      • 2021-10-03
      • 2020-11-10
      • 2020-06-01
      • 2020-08-29
      • 1970-01-01
      • 2021-06-02
      • 1970-01-01
      • 2013-07-28
      • 1970-01-01
      相关资源
      最近更新 更多