Я делаю игру для себя. Проблема, с которой я застрял, заключается в том, что по какой-то причине программа вылетает после помещения некоторых объектов на холст и их удаления. Более подробно:
У меня есть Frame FrameMain
с холстом в нем.
У меня есть Frame FrameLower
с холстом в нем. Также изображение на холсте.
Я помещаю и удаление нескольких FrameLower
как FrameMain.obj
на FrameMain
холст с FrameMain.__placeFrames()
метод.
Проблема в том, что, похоже, память где-то не очищается полностью, когда я удаляю FrameMain.obj
. Таким образом, это приводит к сбою программы через некоторое время, в зависимости от того, сколько раз FrameLower
и сколько изображений у нее на холсте.
У меня достаточно свободной памяти, как вы можете предсказать, ~ 6 ГБ, так что это не проблема.
Я действительно хочу понять, почему он сбой, если есть свободная память для хранения объектов и почему эти объекты не удаляются полностью.
Я действительно хочу избавиться от этой аварии. В следующем упрощенном примере я помещаю 10000 кадров, но в реальной программе 100 из них достаточно, чтобы убить мою игру - они сильно заполнены изображениями.
(Чтобы этот код работал как есть, любой файл img.gif
в корневом каталоге нужен)
from tkinter import *
class FrameMain(Frame):
def __init__(self,master):
super().__init__(master,height=100,width=100,bg='black')
self.grid()
self.canvas=Canvas(self,height=100,width=100,bg='white')
self.canvas.grid()
self.__placeFrames(10000)
def __placeFrames(self,number):
for counter in range(0,number):
self.obj=self.canvas.create_window(50,50,window=FrameLower(self.canvas))
self.canvas.delete(self.obj)
del self.obj
class FrameLower(Frame):
def __init__(self,master):
super().__init__(master,height=50,width=50,bg='red')
self.canvas=Canvas(self,height=50,width=50,bg='blue')
self.canvas.grid()
self.img=PhotoImage(file='img.gif')
self.canvas.create_image(0,0,image=self.img)
def Run():
root=Tk()
frameMain=FrameMain(root)
root.mainloop()
Run()
Когда вы делаете self.canvas.delete(self.obj)
, все, что вы делаете, - это удаление объекта с холста. Рамка, связанная с объектом, не будет уничтожена. Если вы хотите уничтожить оконный объект, вам нужно явно вызвать destroy
на нем.
На холсте также есть некоторые известные ограничения при создании тысяч и тысяч предметов. Он не перерабатывает идентификаторы элементов холста, поэтому они продолжают занимать небольшое количество памяти, даже если сам объект canvas был удален. Одно из решений заключается в том, чтобы не удалять элементы холста, а скорее перемещать их за пределы экрана или настраивать их для скрытия, когда они не нужны, а затем перенастраивать их вместо создания нового элемента.
self.frm=FrameLower(self.canvas)
и self.frm.destroy()
, и получил общее решение о том, как избежать self.frm.destroy()
проблем в будущем. знак равно