Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: __str__ returned non-string (type instance)

Tags:

tkinter

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)
like image 301
the_prole Avatar asked Nov 28 '14 00:11

the_prole


2 Answers

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)
like image 118
the_prole Avatar answered Nov 08 '22 01:11

the_prole


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.

like image 1
Yeheshuah Avatar answered Nov 08 '22 01:11

Yeheshuah