PyQt5: RuntimeError: упакованный объект C / C ++ типа FigureCanvasQTAgg был удален - PullRequest
0 голосов
/ 10 января 2019

Итак, последние пару дней я просматривал сообщения от stackoverflow, чтобы решить эту проблему, и, попробовав несколько вещей, мне все еще не удается заставить работать мой код. Я пытаюсь создать простой графический интерфейс, где я могу показать график при нажатии кнопки. Когда я запускаю свой основной модуль, программа запускается. Но когда я нажимаю кнопку «Сюжет», я получаю сообщение об ошибке

RuntimeError: обернутый объект C / C ++ типа FigureCanvasQTAgg был удален

Теперь я прочитал, что это как-то связано с удалением объекта C ++, в то время как оболочка Python все еще существует, но я не могу решить эту проблему. Моя главная задача - сохранить графический интерфейс как можно более модульным, поскольку я хочу расширить пример кода, показанный ниже. У кого-нибудь есть хорошее решение моей проблемы?

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

1 Ответ

0 голосов
/ 10 января 2019

Каждый раз, когда вы используете PlotFrame(), создается новый объект, и в вашем случае вы создаете 2 объекта в example_figure, но они являются локальными, поэтому они будут автоматически удалены при выполнении этой функции, вызывая указанную вами ошибку, поскольку ссылка теряется При удалении объекта без уведомления 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...