On 2021-02-24 23:23, John O'Hagan wrote:
On Wed, 24 Feb 2021 13:07:24 +0000
MRAB <pyt...@mrabarnett.plus.com> wrote:
On 2021-02-24 11:35, John O'Hagan wrote:
[...]
>
> Here is some minimal, non-threaded code that reproduces the problem
> on my system (Xfce4 on Debian testing):
>
> from tkinter import *
> from random import randint
>
> root = Tk()
>
> def display(label):
> label.destroy()
> label = Label(text=randint(0, 9))
> label.pack()
> root.after(100, display, label)
>
> display(Label())
> mainloop()
>
[...]
> This works for 3-4 hours, but eventually the window freezes.
>
> The process uses about 26 Mb of memory at first, and this gradually
> increases to around 30 or so by the time it freezes.
>
> Any ideas what could be causing this, or even how to approach
> debugging or workarounds?
>
The problem might be that you're adding the label using .pack but not
removing it with .pack_forget when you destroy it.
Try doing both:
from tkinter import *
from random import randint
root = Tk()
def display(label):
if label is not None:
label.pack_forget()
label.destroy()
label = Label(text=randint(0, 9))
label.pack()
root.after(100, display, label)
display(None)
mainloop()
Thanks for the reply, I ran this overnight but unfortunately the result
was the same.
I'm not a tkinter expert at all, but I had gathered from the docs that
calling destroy() on a widget was sufficient to cleanly remove the
widget and all its children. Is that not the case?
In case it's relevant, to clarify what I mean by "freeze": the window
continues to display the digits indefinitely if no attempt is made to
interact with the window, but after some hours have passed, if I click
on the window the digits stop displaying, resizing causes fragmented
images of the desktop to appear in the window, and it cannot be closed
except by terminating the process (e.g, in a task manager).
Hmm. A memory leak perhaps? It's more noticeable if you reduce the
timeout from 100 to 1.
A workaround is to update the label's text instead:
from tkinter import *
from random import randint
root = Tk()
def update():
label.config(text=randint(0, 9))
root.after(1, update)
label = Label()
label.pack()
update()
mainloop()
It's neater anyway.
--
https://mail.python.org/mailman/listinfo/python-list