5

The nub of the matter is, what am I doing wrong in the following code snippet?

    from tkinter import *
    from tkinter.ttk import *

    root = Tk()

    myButton = Button(root)
    myImage = PhotoImage(myButton, file='myPicture.gif')
    myButton.image = myImage
    myButton.configure(image=myImage)

    root.mainloop()

The error message I get from idle3 is as follows:

    >>> 
    Traceback (most recent call last):
      File "/home/bob/Documents/Python/tkImageTest.py", line 9, in <module>
        myButton.configure(image=myImage)
      File "/usr/lib/python3.2/tkinter/__init__.py", line 1196, in configure
        return self._configure('configure', cnf, kw)
      File "/usr/lib/python3.2/tkinter/__init__.py", line 1187, in _configure
        self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
    TypeError: __str__ returned non-string (type Button)
    >>> 

This error message has me stumped, I simply don't understand what it is trying to say. Any ideas?

I would also appreciate suggestions for changes...

5
  • BTW I have already checked this reference effbot.org/tkinterbook/photoimage.htm - you will see my code snippet looks very similar! Commented Jul 22, 2012 at 7:24
  • The error seems to point to the myButton argument passed to PhotoImage(). I don't believe that PhotoImage() takes a reference to a widget object, so this may be causing the error. Try that line without it, such as myImage = PhotoImage(file='myPicture.gif') Commented Jul 22, 2012 at 18:32
  • 1
    @Gary, that seems to do it. I was misled by some of the documentation (and some other errors I had generated) to thinking the PhotoImage needs an explicit reference to the root window. After some more fiddling I found the reference to either the root or the button itself can be provided by another configuration option on the PhotoImage constructor like this, PhotoImage(master=myButton, file='myFile.gif'), but the way I have written it, it looks to Tkinter like a name, which is supposed to be a string, ofc. Commented Jul 23, 2012 at 3:09
  • Got it. Turned my comment into an answer and added some other useful info. Commented Jul 23, 2012 at 13:08
  • See the code given in stackoverflow.com/questions/9142509/… Commented Mar 9, 2017 at 18:35

2 Answers 2

7

The error seems to point to the myButton argument passed to PhotoImage. As you noted in your comment, PhotoImage was treating the widget object as a string (there are several options of type string; see a list of PhotoImage options here).

Your code will work if you implement that line without referencing the myButton object:

myImage = PhotoImage(file='myPicture.gif')

I'm not certain you need to alter the PhotoImage constructor. Look at the PhotoImage docs to determine the valid options (i.e. resource names) for that class. Quoting the help file:

Help on class PhotoImage in module tkinter:

class PhotoImage(Image)

| Widget which can display colored images in GIF, PPM/PGM format.
|    
|  Method resolution order:  
|      PhotoImage  
|      Image  
|      builtins.object  
|    
|  Methods defined here:
|    
|  __getitem__(self, key)  
|      # XXX config  
|    
|  __init__(self, name=None, cnf={}, master=None, **kw)  
|      Create an image with NAME.
|
|      Valid resource names: data, format, file, gamma, height, palette, 
|      width.

FYI: The easiest way to get to the docs from Python at the command line or from IDLE:

from tkinter import PhotoImage
help(PhotoImage)

And lastly, another useful link about this class is at http://tkinter.unpythonic.net/wiki/PhotoImage.

Sign up to request clarification or add additional context in comments.

2 Comments

Many thanks Gary! You are right about the 'master' reference, too. That was a hang-over from some experiments I was doing with multiple threads (best not to ask!).
@Bobble BTW, if this answered the question, please mark it as the accepted answer (this looks something you can do for a few of your questions).
-1

I tested the example with python 2.7.9, 3.2.5, 3.3.5, 3.4.3 in 32bit and 64bit. (Win 8.1 64bit)

The code works.

( in python 3.4.3 64bit I had first an error message.

I've completely uninstalled 3.4.3 and then reinstalled.

Now, the example works also with 3.4.3 64 bit )

# basic code from >>
# http://tkinter.unpythonic.net/wiki/PhotoImage

# extra code -------------------------------------------------------------------------
from __future__ import print_function

try:
    import tkinter as tk
except:
    import Tkinter as tk

import sys
import platform

print ()
print ('python    ', sys.version)
print ('tkinter   ', tk.TkVersion)
print ()
print (platform.platform(),' ',platform.machine())
print ()


# basic code -------------------------------------------------------------------------

root = tk.Tk()

def create_button_with_scoped_image():
    # "w6.gif" >>
    # http://www.inf-schule.de/content/software/gui/entwicklung_tkinter/bilder/w6.gif
    img = tk.PhotoImage(file="w6.gif")  # reference PhotoImage in local variable
    button = tk.Button(root, image=img)
    # button.img = img  # store a reference to the image as an attribute of the widget
    button.image = img  # store a reference to the image as an attribute of the widget
    button.grid()

create_button_with_scoped_image()

tk.mainloop()

4 Comments

Are you sure that's an answer, and more specifically an answer for python-3.x?
A good answer is not only a working answer but also a documented one. There's no point supplying code if the OP doesn't understand it. He/she should learn something from the answer instead of just copy pasting it, that way he/she'd end up asking the same question again next time, only in a different context.
the point is that the response from gary and the Tkinter Wiki for me does not work in Python 3.4.3
I have edit my post; ( in python 3.4.3 64bit I had first an error message. I've completely uninstalled 3.4.3 and then reinstalled. Now, the example works also with 3.4.3 64 bit )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.