Переполнение памяти (?) Сбой на tkinter

1

Я делаю игру для себя. Проблема, с которой я застрял, заключается в том, что по какой-то причине программа вылетает после помещения некоторых объектов на холст и их удаления. Более подробно:

У меня есть 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()
  • 0
    Добро пожаловать на ТАК! Пожалуйста, посмотрите минимальный воспроизводимый пример, чтобы улучшить свой квест.
  • 0
    @ArtemisFowl Большое спасибо за указание на это. Я попытался максимально упростить мой код и добавил более подробное описание проблемы. Надеюсь, что кто-то поможет мне избежать неприятностей. знак равно
Теги:
tkinter
tkinter-canvas

1 ответ

0
Лучший ответ

Когда вы делаете self.canvas.delete(self.obj), все, что вы делаете, - это удаление объекта с холста. Рамка, связанная с объектом, не будет уничтожена. Если вы хотите уничтожить оконный объект, вам нужно явно вызвать destroy на нем.

На холсте также есть некоторые известные ограничения при создании тысяч и тысяч предметов. Он не перерабатывает идентификаторы элементов холста, поэтому они продолжают занимать небольшое количество памяти, даже если сам объект canvas был удален. Одно из решений заключается в том, чтобы не удалять элементы холста, а скорее перемещать их за пределы экрана или настраивать их для скрытия, когда они не нужны, а затем перенастраивать их вместо создания нового элемента.

  • 0
    Спасибо за подробное объяснение механики python, стоящей за этой проблемой. Я смог решить эту проблему, добавив self.frm=FrameLower(self.canvas) и self.frm.destroy() , и получил общее решение о том, как избежать self.frm.destroy() проблем в будущем. знак равно

Ещё вопросы

Сообщество Overcoder
Наверх
Меню