Python tkinter .pack / .pack_forget проблема с памятью - PullRequest
4 голосов
/ 27 марта 2012

Я уже несколько месяцев обучаю себя Python и приступил к изучению некоторых методов графического интерфейса.

Я написал этот простой скрипт на основе примера pack_remove, который нашел в книге. Мой скрипт просто отображает местное и UTC время каждую секунду. Разумеется, разница только в часе, и я все еще хотел бы переотображать каждую секунду.

Скрипт работает, но моя оперативная память постоянно увеличивается с каждым разом. Я начинаю с около 4 МБ, а затем через 2 часа или около того сценарий использует 25 МБ. Это имеет некоторый смысл для меня, но мне было любопытно, если бы был способ отображать новые времена каждую секунду, но уменьшить использование памяти такого простого дисплея часов.

Или я использую неэффективную технику для отображения данных в графическом интерфейсе с высокой частотой?

Вот мой код:

from tkinter import *
import time

class TimeDisplay(Frame):
    def __init__(self,msecs = 1000):
        Frame.__init__(self)
        self.msecs = msecs
        self.pack()
        utc_time = Label(self, text='')
        utc_time.pack()
        cst_time = Label(self, text='')
        cst_time.pack()
        self.utc_time = utc_time
        self.cst_time = cst_time
        self.repeater()

    def repeater(self):
        self.utc_time.pack_forget()
        self.cst_time.pack_forget()
        self.utc_time = Label(self, text= 'UTC: ' + time.strftime('%Y/%m/%d %H:%M:%S',time.gmtime()))
        self.utc_time.pack()
        self.utc_time.config(bg='navy',fg='white')
        self.cst_time = Label(self, text= 'CST: ' + time.strftime('%Y/%m/%d %H:%M:%S',time.localtime()))
        self.cst_time.pack()
        self.cst_time.config(bg='navy',fg='white')
        self.after(self.msecs, self.repeater)        


if __name__ == '__main__': TimeDisplay(msecs=1000).mainloop()    

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 28 марта 2012

pack_forget ничего не разрушает, просто делает его невидимым.Это GUI-версия утечки памяти - вы продолжаете создавать объекты, даже не уничтожая их.

Итак, первый урок, который нужно усвоить, это то, что вы должны уничтожить виджет, когда закончите с ним.

Более важный урок для изучения заключается в том, что вам не нужно постоянно уничтожать и воссоздавать один и тот же виджет.Вы можете изменить текст, отображаемый с помощью метода configure.Например:

self.utc_time.configure(text="...")

Это позволит вашей программе не использовать лишнюю память и даже использовать (незаметно) меньше ЦП.

1 голос
/ 27 марта 2012

Чтобы фактически освободить память виджета, вы также должны вызвать его метод .destroy (). Это предотвращает утечку памяти в вашем случае.

Однако, более эффективный способ реализовать это - связать строковую переменную с виджетом Label следующим образом:

v = StringVar()
Label(master, textvariable=v).pack()
v.set("New Text!")

см. http://effbot.org/tkinterbook/label.htm для справки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...