Fwd: Tkinter: image handling: bug or feature?

Jose' Sebrosa sebrosa at artenumerica.com
Fri Jun 1 12:18:27 EDT 2001


johngrayson at home.com wrote:
> 
> --- In python-list at y..., Jose' Sebrosa <sebrosa at a...> wrote:
> 
> >> Hi,
> >>
> >> I just figured out that this code
> >>
> >> I like to use local names to everything I can (so the names are not
> >>available when mainloop is called)
> >>
> >> Or I'm simplly messing it all...
> 
> Yes, you're messing it up...   :-)
> 
> If you insist on using local variables, then python is happily
> decrementing their reference count as your 'constructor' goes
> out of scope and they get garbage collected...
> 
> The convention is to make images instance variables. If you are
> paranoid about seeing the variables, mangle their names:
> 
>     self.__secret_image = ....

Thank's very much for your answer.

But...

Of course that when I write 
        my_img = PhotoImage(file = 'my_image.gif' )

inside a function or method, the reference my_img gets discarded when the
function exits. I understand that. The problem is that when I use this
reference to define an option for a Label instance in
        Label(self, image = my_img, bg = 'yellow').pack()

it should (at least I expected so) generate another reference to the same
object. But surprinsingly it seems don't.

This is quite different from what happen when I do the same with a text instead
an image. The code

##########################################################
from Tkinter import *
#
class TextIsNice(Toplevel):
    def __init__(self, master):
        Toplevel.__init__(self, master = master)
        my_txt = 'Text is nice!'
        Label(self, text = txt, bg = 'yellow').pack()
#
if __name__ == '__main__':  TextIsNice(None).mainloop()
##########################################################

works just fine, as I expected from Python usual behavior. So again, what's
wrong with images?

Maybe this has some relation with something special about PhotoImage: In the
debuging procedure, when I understood the need of explicitly keep a reference
to the image generated by PhotoImage, I tried this (which I thougth, naif me,
to be the same as declaring the reference global):

##########################################################
from Tkinter import *
#
my_img = PhotoImage(file = 'my_image.gif') # <-- GLOBAL !!
#
class NotSoFunny(Toplevel):
    def __init__(self, master):
        Toplevel.__init__(self, master = master)
        Label(self, image = my_img, bg = 'yellow').pack()
#
if __name__ == '__main__':  NotSoFunny(None).mainloop()
##########################################################

On execution Python presented me this traceback:

Traceback (innermost last):
  File "<stdin>", line 4, in ?
  File "/usr/lib/python1.5/lib-tk/Tkinter.py", line 1874, in __init__
    apply(Image.__init__, (self, 'photo', name, cnf, master), kw)
  File "/usr/lib/python1.5/lib-tk/Tkinter.py", line 1825, in __init__
    raise RuntimeError, 'Too early to create image'
RuntimeError: Too early to create image

So PhotoImage itself seems to need "something more". The only thing I can
imagine is PhotoImage needing to have "something" defined in its environment,
and that this "something" is silently defined by *others* (which looks poor
style to me). So I tried

##########################################################
from Tkinter import *
#
dummy_call_to_perform_magic_under_the_wood = Tk()
#
my_img = PhotoImage(file = 'my_image.gif') # <-- GLOBAL !!
#
class NotSoFunny(Toplevel):
    def __init__(self, master):
        Toplevel.__init__(self, master = master)
        Label(self, image = my_img, bg = 'yellow').pack()
#
if __name__ == '__main__':  NotSoFunny(None).mainloop()
##########################################################

and it worked "fine" (as far as we can say "fine" about voodoo code like this).

So yet again, what's wrong with images?

Thanks again, 
Sebrosa



More information about the Python-list mailing list