I keep getting this really strange error that I cannot solve looking at any other post. I'm applying a background image to a tkinter canvas.
import Tkinter as tk ## Python 2.X
import Image
root = tk.Tk();
background = "background.png"
photo = tk.PhotoImage(Image.open(background))
canvas = tk.Canvas(root, width=500, height=500)
canvas.pack()
canvas.create_image(0, 0, anchor="nw", image=photo)
root.mainloop()
But because of the last line, I get this error:
Traceback (most recent call last):
File "main.py", line 40, in <module>
canvas.create_image(0, 0, anchor="nw", image=photo)
File "c:\Python27\lib\lib-tk\Tkinter.py", line 2279, in create_image
return self._create('image', args, kw)
File "c:\Python27\lib\lib-tk\Tkinter.py", line 2270, in _create
*(args + self._options(cnf, kw))))
TypeError: __str__ returned non-string (type instance)
Looks like I answered my own question. First of all, I wrote the syntactically incorrect statements:
background = "background.png"
photo = tk.PhotoImage(Image.open(background))
This should be written correctly:
background = "background.png"
photo = tk.PhotoImage(background)
Second, Tkinter does not support .png files. The correct class is ImageTk from module PIL.
from PIL import ImageTk as itk
background = "background.png"
photo = itk.PhotoImage(file = background)
And notice the difference in syntax:
photo = tk.PhotoImage(background)
photo = itk.PhotoImage(file = background)
In additional to the_prole's post
Regarding to PIL reference
Warning
There is a bug in the current version of the Python Imaging Library that can cause your images not to display properly. When you create an object of class PhotoImage, the reference count for that object does not get properly incremented, so unless you keep a reference to that object somewhere else, the PhotoImage object may be garbage-collected, leaving your graphic blank on the application.
For example, if you have a canvas or label widget that refers to such an image object, keep a list named .imageList in that object, and append all PhotoImage objects to it as they are created. If your widget may cycle through a large number of images, you will also want to delete the objects from this list when they are no longer in use.
Your code will be as below
import Tkinter as tk
from PIL import ImageTk as itk
root = tk.Tk();
background = 'background.png'
photo = itk.PhotoImage(file= background)
canvas = tk.Canvas(root, width=500, height=500)
canvas.imageList = []
canvas.pack()
canvas.create_image(0, 0, anchor="nw", image=photo)
canvas.imageList.append(photo)
root.mainloop()
Also, about transparent PNG:
For example in Photoshop, when you save a picture as PNG, PNG options also can cause your images not to display properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With