Newbie Tkinter Question

Discussion in 'Python' started by Pseud O'Nym, Apr 13, 2005.

  1. Pseud O'Nym

    Pseud O'Nym Guest

    Hi,

    the following fragment doesn't cause any errors and results in buttons the
    correct size for the images, but the buttons don't work, and the images
    aren't displayed. If I add a text property, and remove the images, they work
    fine, so the rest of my code's OK. I've searched this group and Python.org
    to no avail.

    class App:
    def __init__(self, master):
    frame = Frame(master)
    frame.pack(side=LEFT, fill=Y)
    image1 = PhotoImage(file='button_a.gif')
    self.button = Button(frame, image=image1)
    self.button.pack(side=TOP)

    Can anyone enlighten me?
     
    Pseud O'Nym, Apr 13, 2005
    #1
    1. Advertisements

  2. Pseud O'Nym

    Paul Rubin Guest

    "Pseud O'Nym" <> writes:
    > class App:
    > def __init__(self, master):
    > frame = Frame(master)
    > frame.pack(side=LEFT, fill=Y)
    > image1 = PhotoImage(file='button_a.gif')
    > self.button = Button(frame, image=image1)
    > self.button.pack(side=TOP)
    >
    > Can anyone enlighten me?


    You do have this inside a frame whose main loop is running, I hope?
     
    Paul Rubin, Apr 13, 2005
    #2
    1. Advertisements

  3. Pseud O'Nym

    Peter Otten Guest

    Pseud O'Nym wrote:

    > the following fragment doesn't cause any errors and results in buttons the
    > correct size for the images, but the buttons don't work, and the images
    > aren't displayed. If I add a text property, and remove the images, they
    > work fine, so the rest of my code's OK. I've searched this group and
    > Python.org to no avail.
    >
    > class App:
    > def __init__(self, master):
    > frame = Frame(master)
    > frame.pack(side=LEFT, fill=Y)
    > image1 = PhotoImage(file='button_a.gif')
    > self.button = Button(frame, image=image1)
    > self.button.pack(side=TOP)


    self.image = image1

    > Can anyone enlighten me?


    For reasons that are beyond me widgets do not increase the reference count
    of a PhotoImage. Therefore you have to put a reference to the image
    elsewhere, e. g. into the App instance, to prevent it from being
    garbage-collected when the image1 variable goes out of scope.

    Peter
     
    Peter Otten, Apr 14, 2005
    #3
  4. Peter Otten schrieb:
    > Pseud O'Nym wrote:
    >
    >
    >>the following fragment doesn't cause any errors and results in buttons the
    >>correct size for the images, but the buttons don't work, and the images
    >>aren't displayed. If I add a text property, and remove the images, they
    >>work fine, so the rest of my code's OK. I've searched this group and
    >>Python.org to no avail.
    >>
    >>class App:
    >> def __init__(self, master):
    >> frame = Frame(master)
    >> frame.pack(side=LEFT, fill=Y)
    >> image1 = PhotoImage(file='button_a.gif')
    >> self.button = Button(frame, image=image1)
    >> self.button.pack(side=TOP)

    >
    >
    > self.image = image1
    >
    >
    >>Can anyone enlighten me?

    >
    >
    > For reasons that are beyond me widgets do not increase the reference count
    > of a PhotoImage. Therefore you have to put a reference to the image
    > elsewhere, e. g. into the App instance, to prevent it from being
    > garbage-collected when the image1 variable goes out of scope.
    >
    > Peter
    >

    Because I stumbled across the same 'feature' just recently, I think it's
    good to give a reference...

    From http://tkinter.unpythonic.net/wiki/Images

    "Something that seems to bite every new Tkinter programmer at least
    once: you've loaded a PhotoImage, applied it to a Button, Label, or
    other widget, and nothing shows up - because you referenced the image
    only via a local variable, so it went out of scope and got deleted
    before the widget ever appeared. The usual solution is to store a
    reference to the image as an attribute of the widget that is to display it.

    You might just call this a bug in Tkinter, but the reality isn't quite
    that simple... Tk images are not first-class objects: when you apply one
    to a widget, you do not in any sense "pass a reference to" the image.
    Instead, you just pass a name, which Tk looks up in an internal table of
    defined images (from which images can only be deleted manually). From
    Tkinter, passing a PhotoImage as a parameter actually only sends the
    str() of the image object to the Tcl side: this is just a string, the
    randomly-generated name assigned when the object was created. "No
    reference to the image itself" means "no reference counting" means "no
    way for the Python side to be notified when the image is truly no longer
    used". If Tkinter didn't delete images when no Python reference to them
    existed, they would be unavoidable memory leaks.
    ...."

    Hans Georg
     
    Hans Georg Krauthaeuser, Apr 14, 2005
    #4
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael
    Replies:
    2
    Views:
    700
    Michael Peuser
    Aug 31, 2003
  2. Porky Pig Jr
    Replies:
    3
    Views:
    1,463
    Fuzzyman
    May 12, 2004
  3. Hornberger, Chris
    Replies:
    1
    Views:
    534
    Alan Gauld
    May 12, 2004
  4. Andy Baker
    Replies:
    2
    Views:
    516
    Leif B. Kristensen
    May 12, 2004
  5. Andr? Roberge

    Newbie question about Tkinter

    Andr? Roberge, Aug 16, 2004, in forum: Python
    Replies:
    1
    Views:
    317
    Christopher T King
    Aug 16, 2004
  6. Wim Goffin

    Newbie question Tkinter bitmap

    Wim Goffin, Mar 12, 2005, in forum: Python
    Replies:
    0
    Views:
    419
    Wim Goffin
    Mar 12, 2005
  7. Wim Goffin

    Python Tkinter Newbie question

    Wim Goffin, Mar 12, 2005, in forum: Python
    Replies:
    2
    Views:
    379
    Harlin Seritt
    Mar 12, 2005
  8. Jerry C.
    Replies:
    8
    Views:
    576
    Uri Guttman
    Nov 23, 2003
Loading...