RuntimeError: Internal C++ object (PySide2.QtWidgets.QGraphicsPixmapItem) already deleted

RuntimeError: Internal C++ object (PySide2.QtWidgets.QGraphicsPixmapItem) already deleted

我有一个 class 帧渲染器

class FrameRenderer():

    simulation = None 
    scene = None 
    timer = None 

    def __init__(self, simulation, scene):
        self.simulation = simulation
        self.scene = scene
        self.timer = QTimer()
        self.timer.timeout.connect(self.nextFrame)
        self.timer.setInterval(1000/30)# 30 Frames per second  

    #Render one time step 
    def nextFrame(self):
        for food in self.simulation.food:
            food.xPos = food.xPos + randint(-1,1)
            food.yPos = food.yPos + randint(-1,1)
            if food.pixmap:
                food.pixmap.setPos(food.xPos, food.yPos)

    def start(self):
        self.timer.start()

    def pause(self):
        self.timer.stop()

为了测试,我只是让我的像素图随机移动。它是从第二个 class SimulationView

调用的
class SimulationView():

    mainWindow = None
    graphicsScene = None 
    simWindow = None
    simulation = None
    isSimulating = False  
    simulationStarted = False 
    frameRenderer = None 
    beginSimulationButton = None 
    cancelSimulationButton = None 
    toggleSimulationButton = None 
    foodSlider = None 
    BUFFER = 10 #ensure we don't drop items too close to the extremes of the scene 


    def __init__(self, mainWindow):

        self.mainWindow = mainWindow

        self.simWindow = mainWindow.simulation_window

        #connect QWidgets to functions 
        self.beginSimulationButton = mainWindow.begin_simulation_button
        self.beginSimulationButton.clicked.connect(self.simulate)

        self.cancelSimulationButton = mainWindow.cancel_simulation_button
        self.cancelSimulationButton.clicked.connect(self.cancelSimulation)

        self.toggleSimulationButton = mainWindow.toggle_simulation_button
        self.toggleSimulationButton.clicked.connect(self.toggleSimulation)

        self.foodSlider = mainWindow.food_slider

    def createGraphicsScene(self):
        #create new scene 
        self.graphicsScene = QGraphicsScene()
        self.graphicsScene.setSceneRect(self.simWindow.x(), self.simWindow.y(), self.simWindow.width() - self.BUFFER, self.simWindow.height() - self.BUFFER)
        self.simWindow.setScene(self.graphicsScene)

    #draw the food items to the screen and create new food objects 
    def drawFood(self, foodAmount):
        for _ in range(foodAmount):
            food_x = randint(self.BUFFER, self.graphicsScene.width() - self.BUFFER)
            food_y = randint(self.BUFFER, self.graphicsScene.height() - self.BUFFER)
            newFood = Food(food_x,food_y)
            self.simulation.addFood(newFood)
            self.graphicsScene.addItem(newFood.pixmap)
            newFood.pixmap.setPos(food_x, food_y)

    #call the correct function based on the simulation state
    def simulate(self):
        self.start()
        self.isSimulating = True 
        self.simulationStarted = True

    #start the simulation 
    def start(self):
        self.createGraphicsScene()
        self.simulation = Simulation(self.mainWindow)
        self.frameRenderer = FrameRenderer(self.simulation, self.graphicsScene)
        self.drawFood(self.foodSlider.sliderPosition())
        self.frameRenderer.start() 

    #toggle whether or not we are current simulating 
    def toggleSimulation(self):

        if not self.simulationStarted:
            return 

        if self.isSimulating:
            self.frameRenderer.pause()
        else:
            self.frameRenderer.start()

        self.isSimulating = not self.isSimulating

    #clear sim window
    def cancelSimulation(self):
        self.frameRenderer = None
        self.simulation = None
        self.createGraphicsScene()
        self.isSimulating = False 
        self.simulationStarted = False 

代码工作正常,直到我取消然后重新开始模拟。如果我这样做,我会得到 RuntimeError: Internal C++ object (PySide2.QtWidgets.QGraphicsPixmapItem) already deleted.。这是正确的,因为我确实在按下开始时创建了一个新的模拟对象,但它也被传递给了构造函数,这意味着它不应该引用我的旧模拟。我不确定为什么重新创建资产不会让我再次绘制

我曾尝试将帧渲染器显式设置为 None 试图将其置于范围之外,但这似乎无济于事

将图形场景设置为 None 不足以触发 Qt 导致底层 c++ 解构器为 运行。为了让场景被删除,我必须先清空场景 然后 删除它

for item in self.graphicsScene.items():
    self.graphicsScene.removeItem(item)