Problem displaying images with TkInter

Discussion in 'Python' started by David, Mar 4, 2004.

  1. David

    David Guest

    Hi,
    I'm new to python so I'm probably making a fairly simple mistake, but
    look at the example below. It simply displays a rectangle and an image.

    -------------------------------------------------
    from Tkinter import *

    root = Tk()

    c = Canvas(root, width=1024, height = 1024)
    c.pack()

    c.create_rectangle(10,10,50,50)
    mudPhoto = PhotoImage(file="/root/metropolis/mud.gif")
    c.create_image(50, 50, anchor=NW, image=mudPhoto)

    root.mainloop()
    -----------------------------------------------

    Now I try to modify it so that the image and rectangle only appear when I
    click the mouse on the canvas. I use the following code:

    -----------------------------------------------
    from Tkinter import *

    root = Tk()

    def OnClick(event):
    print "click!!!"
    c.create_rectangle(10,10,50,50)
    mudPhoto = PhotoImage(file="/root/metropolis/mud.gif")
    c.create_image(50, 50, anchor=NW, image=mudPhoto)

    c = Canvas(root, width=1024, height = 1024)
    c.pack()
    c.bind("<Button-1>",OnClick)
    root.mainloop()
    ----------------------------------------------

    However when I click the mouse it prints 'click!!!' and draws the rectangle
    as expected. However it doesn't draw the image! Does anyone have any idea
    why this would be?

    Thanks for any help,

    David
     
    David, Mar 4, 2004
    #1
    1. Advertising

  2. David

    Eric Brunel Guest

    David wrote:
    > Hi,
    > I'm new to python so I'm probably making a fairly simple mistake, but
    > look at the example below. It simply displays a rectangle and an image.
    >
    > -------------------------------------------------
    > from Tkinter import *
    >
    > root = Tk()
    >
    > c = Canvas(root, width=1024, height = 1024)
    > c.pack()
    >
    > c.create_rectangle(10,10,50,50)
    > mudPhoto = PhotoImage(file="/root/metropolis/mud.gif")
    > c.create_image(50, 50, anchor=NW, image=mudPhoto)
    >
    > root.mainloop()
    > -----------------------------------------------
    >
    > Now I try to modify it so that the image and rectangle only appear when I
    > click the mouse on the canvas. I use the following code:
    >
    > -----------------------------------------------
    > from Tkinter import *
    >
    > root = Tk()
    >
    > def OnClick(event):
    > print "click!!!"
    > c.create_rectangle(10,10,50,50)
    > mudPhoto = PhotoImage(file="/root/metropolis/mud.gif")
    > c.create_image(50, 50, anchor=NW, image=mudPhoto)
    >
    > c = Canvas(root, width=1024, height = 1024)
    > c.pack()
    > c.bind("<Button-1>",OnClick)
    > root.mainloop()
    > ----------------------------------------------
    >
    > However when I click the mouse it prints 'click!!!' and draws the rectangle
    > as expected. However it doesn't draw the image! Does anyone have any idea
    > why this would be?


    This used to be a FAQ, but I can't it anymore (anyone knows where it has gone?).

    The problem lies in the fact that for some reason, the Canvas where you do the
    create_image does *not* keep a reference on the actual PhotoImage object. So
    this object disappears when your variable mudPhoto goes out of scope (i.e. at
    the end of your OnClick function), which causes its deletion at tk level. So
    when OnClick finishes, the canvas finds itself displaying an image that doesn't
    exist anymore.

    The workaround is simple: always keep an explicit reference on all your
    PhotoImage and BitmapImage objects until you no more need them. For your
    particular case, this can be done via:

    def OnClick(event):
    print "click!!!"
    c.create_rectangle(10,10,50,50)
    c.mudPhoto = PhotoImage(file="/root/metropolis/mud.gif")
    c.create_image(50, 50, anchor=NW, image=c.mudPhoto)

    Turning mudPhoto into an attribute of the canvas ensures that it won't be
    deleted before the canvas is.

    HTH
    --
    - Eric Brunel <eric dot brunel at pragmadev dot com> -
    PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com
     
    Eric Brunel, Mar 4, 2004
    #2
    1. Advertising

  3. David

    David Guest

    Ok, that's working now. Thanks for the tip!

    David

    Eric Brunel wrote:

    > David wrote:
    >> Hi,
    >> I'm new to python so I'm probably making a fairly simple mistake,
    >> but
    >> look at the example below. It simply displays a rectangle and an image.
    >>
    >> -------------------------------------------------
    >> from Tkinter import *
    >>
    >> root = Tk()
    >>
    >> c = Canvas(root, width=1024, height = 1024)
    >> c.pack()
    >>
    >> c.create_rectangle(10,10,50,50)
    >> mudPhoto = PhotoImage(file="/root/metropolis/mud.gif")
    >> c.create_image(50, 50, anchor=NW, image=mudPhoto)
    >>
    >> root.mainloop()
    >> -----------------------------------------------
    >>
    >> Now I try to modify it so that the image and rectangle only appear when I
    >> click the mouse on the canvas. I use the following code:
    >>
    >> -----------------------------------------------
    >> from Tkinter import *
    >>
    >> root = Tk()
    >>
    >> def OnClick(event):
    >> print "click!!!"
    >> c.create_rectangle(10,10,50,50)
    >> mudPhoto = PhotoImage(file="/root/metropolis/mud.gif")
    >> c.create_image(50, 50, anchor=NW, image=mudPhoto)
    >>
    >> c = Canvas(root, width=1024, height = 1024)
    >> c.pack()
    >> c.bind("<Button-1>",OnClick)
    >> root.mainloop()
    >> ----------------------------------------------
    >>
    >> However when I click the mouse it prints 'click!!!' and draws the
    >> rectangle as expected. However it doesn't draw the image! Does anyone
    >> have any idea why this would be?

    >
    > This used to be a FAQ, but I can't it anymore (anyone knows where it has
    > gone?).
    >
    > The problem lies in the fact that for some reason, the Canvas where you do
    > the create_image does *not* keep a reference on the actual PhotoImage
    > object. So this object disappears when your variable mudPhoto goes out of
    > scope (i.e. at the end of your OnClick function), which causes its
    > deletion at tk level. So when OnClick finishes, the canvas finds itself
    > displaying an image that doesn't exist anymore.
    >
    > The workaround is simple: always keep an explicit reference on all your
    > PhotoImage and BitmapImage objects until you no more need them. For your
    > particular case, this can be done via:
    >
    > def OnClick(event):
    > print "click!!!"
    > c.create_rectangle(10,10,50,50)
    > c.mudPhoto = PhotoImage(file="/root/metropolis/mud.gif")
    > c.create_image(50, 50, anchor=NW, image=c.mudPhoto)
    >
    > Turning mudPhoto into an attribute of the canvas ensures that it won't be
    > deleted before the canvas is.
    >
    > HTH
     
    David, Mar 5, 2004
    #3
    1. Advertising

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. Cloud Burst
    Replies:
    8
    Views:
    615
    Gary Mc
    Jan 14, 2004
  2. Jim Easterbrook

    Re: displaying video in a tkinter GUI

    Jim Easterbrook, Aug 22, 2003, in forum: Python
    Replies:
    0
    Views:
    2,120
    Jim Easterbrook
    Aug 22, 2003
  3. Fuzzyman
    Replies:
    0
    Views:
    364
    Fuzzyman
    Jan 28, 2004
  4. Replies:
    0
    Views:
    283
  5. Replies:
    2
    Views:
    506
    Daniel Pitts
    Mar 7, 2007
Loading...

Share This Page