我有一个类框架渲染器
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()
为了进行测试,我只是让我的像素图随机移动。从第二个类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.
。这是正确的,因为在按下begin时确实创建了一个新的模拟对象,但它也传递给了构造函数,这意味着它不应引用我的旧模拟对象。我不确定为什么重新创建资产不会让我再次绘画
我试图将帧渲染器显式设置为None,试图将其超出范围,但这似乎无济于事
答案 0 :(得分:0)
将图形场景设置为None
不足以触发Qt导致底层c ++解构函数运行。为了删除场景,我必须先清空场景然后删除它
for item in self.graphicsScene.items():
self.graphicsScene.removeItem(item)