Python memory issue tkinter.pack / .pack_forget

I have been teaching Python for several months and am starting to learn some GUIs.

I wrote this simple script based on the pack_remove example that I found in the book. My script just displays local and UTC time every second. Of course, the only difference is the hour, I would still like to redraw every second.

The script is running, but my RAM is constantly increasing with every impression. I start with 4 MB, then after 2 hours or so the script uses 25 MB. It does matter to me, but I was curious if there is a way to display new times every second, but reduce the memory usage of such a simple clock display.

Or am I using an inefficient technique to redisplay data in a GUI at high frequency?

Here is my code:

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() 

Thanks in advance

+4
source share
2 answers

pack_forget doesn’t destroy anything, it just makes it invisible. This is a GUI version of a memory leak - you continue to create objects without destroying them.

So, the first lesson to learn is that you must destroy the widget when you are done with it.

A more important lesson to learn is that you don’t need to continue to destroy and recreate the same widget over and over again. You can change the text displayed using the configure method. For instance:

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

This will cause your program not to use extra memory and even use (imperceptibly) less CPU.

+1
source

To actually free up widget memory, you must also call it .destroy () method. This prevents a memory leak in your case.

However, a more efficient way to implement this material is to associate a string variable with a Label widget as follows:

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

see http://effbot.org/tkinterbook/label.htm for reference

0
source

Source: https://habr.com/ru/post/1403727/


All Articles