I am creating a basic hangman game using tkinter. The last thing that I need to do is to add a widget that has an image to show the actual hangman. However, I keep getting this error whenever I try anything:

  File "C:\Program Files (x86)\Python\lib\tkinter\__init__.py", line 3287, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "C:\Program Files (x86)\Python\lib\tkinter\__init__.py", line 3243, in __init__
    self.tk.call(('image', 'create', imgtype, name,) + options)
  _tkinter.TclError

I am presuming that I should use PhotoImage, as all the images are in .gif format. I have commented in the code below what needs to go where as far as I think. As it is below, it runs fine. This one uses a massive dictionary file so for the sake of debugging I suggest that you guys make a small list of words.

import random,time
from tkinter import *

def guess():
    global losses
    letter=e1.get().strip()
    if len(letter)!=1 or type(letter)!=str or letter in used:
        game.insert(END,'INVALID INPUT')
    else:
        used.append(letter)
        if letter in secret:
            game.insert(END,"\n",'Correct!')
            positions=[i for i,item in enumerate(secret) if item==letter]
            for place in positions:
                display[place]=letter
        else:
            game.insert(END,"\n",'Incorrect.')
            losses+=1
            #change image here -images go from 0 to 6.gif and correspond with the variable losses
        game.insert(END,''.join(display),'Used: ' + ''.join(used))
        if losses==6:
            game.insert(END,'You Lose.')
        elif display==secret:
            game.insert(END,'You Win!')
        game.yview(END)


def new_game():
    global photo,losses,used,secret,display

    secret=list(random.choice(open('dictionary.txt').readlines()))
    del secret[-1]

    #reset image back to first image

    losses=0
    used=[]
    display=['*' for letter in secret]

    game.delete(0,END)
    game.insert(END,''.join(display))

master=Tk()
master.title('PyHang 2.0')

Label(master,text='Guess').grid(row=2)
e1=Entry(master)
e1.grid(row=2,column=1)

slider=Scrollbar(master)
slider.grid(row=1,column=2)
game=Listbox(master,yscrollcommand=slider.set)
game.config(height=3)
game.grid(row=1,column=1)
slider.config(command=game.yview)

#create original widget, first image is "\images\0.gif" in an external folder

Button(master,text='OK',command=guess).grid(row=2,column=2)
Button(master,text="New\nGame",command=new_game).grid(row=1,column=0)

new_game()

mainloop()

I know that the code in the guess function is hideous, and this program should probably be in class format but that's for another day. FYI, this is my first tkinter program so if the answer's really obvious, please be patient. Any assistance would be greatly appreciated.

Recommended Answers

All 5 Replies

An example of placing a gif image on a canvas Click Here Most people who are attempting a hangman game use a canvas and [draw lines, circles] (http://effbot.org/tkinterbook/canvas.htm) etc. to get the hangman, but it is your program. You might also consider a Toplevel i.e. a second window for the hangman image

@woooee still getting the same error with this code:

import random,time
from tkinter import *

def guess(event=None):
    global losses
    letter=e1.get().strip()
    if len(letter)!=1 or type(letter)!=str or letter in used:
        game.insert(END,'INVALID INPUT')
    else:
        used.append(letter)
        if letter in secret:
            game.insert(END,"\n",'Correct!')
            positions=[i for i,item in enumerate(secret) if item==letter]
            for place in positions:
                display[place]=letter
        else:
            game.insert(END,"\n",'Incorrect.')
            losses+=1
            #change image here -images go from 0 to 6.gif and correspond with the variable losses
        game.insert(END,''.join(display),'Used: ' + ''.join(used))
        if losses==6:
            game.insert(END,'You Lose.',"'" + ''.join(secret) + "'")
        elif display==secret:
            game.insert(END,'You Win!')
    game.yview(END)


def new_game():
    global photo,losses,used,secret,display

    secret=list(random.choice(open('dictionary.txt').readlines()))
    del secret[-1]

    #reset image back to first image
    level=PhotoImage(file='images\0.gif')
    hangmanpic.create_image(0,0,image=level,anchor=SW)

    losses=0
    used=[]
    display=['*' for letter in secret]

    game.delete(0,END)
    game.insert(END,''.join(display))

master=Tk()
master.title('PyHang 2.0')

Label(master,text='Guess').grid(row=2)
e1=Entry(master)
e1.grid(row=2,column=1)

slider=Scrollbar(master)
slider.grid(row=1,column=2)
game=Listbox(master,yscrollcommand=slider.set)
game.config(height=3)
game.grid(row=1,column=1)
slider.config(command=game.yview)

#create original widget, first image is "\images\0.gif" in an external folder
hangmanpic=Canvas(width=220,height=125)
hangmanpic.grid(row=0,column=1)

Button(master,text='OK',command=guess).grid(row=2,column=2)
master.bind('<Return>', guess)
Button(master,text="New\nGame",command=new_game).grid(row=1,column=0)

game.insert(END,'Welcome!',"Press 'New Game'.",'By Alex Thornton')

mainloop()

I mean, it creates the canvas but poops itself when I try to assign an image. Oh and sorry about the earlier question about canvases taking up unnecessary code, I hadn't realised it was basically just a more specialised kind of label. The full error code:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python\lib\tkinter\__init__.py", line 1456, in __call__
    return self.func(*args)
  File "E:\Private\Year 10\Documents\Computing\demo\hangman\pyhang2.py", line 35, in new_game
    level=PhotoImage(file='images\0.gif')
  File "C:\Program Files (x86)\Python\lib\tkinter\__init__.py", line 3287, in __init__
    Image.__init__(self, 'photo', name, cnf, master, **kw)
  File "C:\Program Files (x86)\Python\lib\tkinter\__init__.py", line 3243, in __init__
    self.tk.call(('image', 'create', imgtype, name,) + options)
_tkinter.TclError

Now that you have posted the complete error message we know which line is causing it.

level=PhotoImage(file='images\0.gif')

does not look like a valid file name. It is perhaps "/images/0.gif". But that probably is not enough either as you have to provide the complete file name "/path/to/file/images/0.gif". You also must keep a reference to the image object in your Python program, either by storing it in a global variable, or by attaching it to another object. You might want to use something like this just to be on the safe side

fname="/path/to/file/images/0.gif"
if os.path.isfile(fname):
    level=PhotoImage(file=fname)
else:
    print "File not found", fname

If that still doesn't work, then download a gif image from the web to test with as it may be the image that is causing the problem.

commented: good help +14

Improve woooee's idea by raising an exception

class HangmanError(Exception):
    pass

# ...   

fname="/path/to/file/images/0.gif"
if os.path.isfile(fname):
    level=PhotoImage(file=fname)
else:
    raise HangmanError(("No such file:", fname))

Looks like you have a series of hang images in an external folder. Prefix the image names with the full path to this folder. By the way, you can use the foreward slash '/' with Windows, this way you can avoid a raw string designation.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.