0

New to python and so far mostly love it but this issue is odd. The exact same code works from the root but not in a method.

This does not render the image:

from tkinter import *      
root = Tk() 

def draw():
    print("does not work")
    canvas = Canvas(root, width = 300, height = 300)      
    canvas.pack()      
    img = PhotoImage(file="Db.png")      
    canvas.create_image(20,20, anchor=NW, image=img)      

draw()
mainloop()  

But this works fine:

from tkinter import *      
root = Tk() 

print("This works fine")
canvas = Canvas(root, width = 300, height = 300)      
canvas.pack()      
img = PhotoImage(file="Db.png")      
canvas.create_image(20,20, anchor=NW, image=img)      

mainloop()

Any help would be appreciated.

martineau
  • 119,623
  • 25
  • 170
  • 301
DKnight
  • 1
  • 1
  • In the version with the `draw()` function, `img` is a local variable which gets deleted when the function returns. In the other version it's a global variable and continues to exist after a value is assigned to it and more importantly while `mainloop()` is executing. Change the function version to `root.img = PhotoImage(file="Db.png")` to and use `canvas.create_image(20,20, anchor=NW, image=root.img)` avoid the problem. – martineau Jan 31 '19 at 22:12
  • This `PhotoImage` class [documentation](http://effbot.org/tkinterbook/photoimage.htm) discusses the need to do this. See the portion starting at "You must keep a reference to the image object..." – martineau Jan 31 '19 at 22:24
  • @martineau That makes perfect sense. Thank you, I've been banging my head against this in it's more complex implementation in my code before breaking it down to the above. – DKnight Jan 31 '19 at 23:24
  • DKnight; Don't feel too bad. The problem is because the functions and classes in the `tkinter` interface don't behave like normal Python objects—which automatically do reference counting which makes doing stuff like this unnecessary. – martineau Jan 31 '19 at 23:38

1 Answers1

0

As martineau explains in the comments above the problem with the code is that the img variable only exists while the function is processing, it is deleted after the function returns and it's required that I keep a reference to the image object. Making it a global variable corrects the issue.

Many Thanks!

DKnight
  • 1
  • 1