Tkinter: Error with Button and Entry Widget Logic

Viewed 30

I'm developing a GUI for a simple PC game in Python, and I am currently having difficulties with storing a value that the program prompts a user to input through a tkinter.Entry widget. I have used this widget successfully before with the same logic that I have provided in my code below and yet, I am receiving a traceback: 'NameError object not defined'. In particular, when I run the program, a canvas widget and accompanying button, label, and entry widgets are successfully generated. However, when I input a string through the entry field widget and activate the "Submit" button, the interpreter gives me an error indicating that the object I am storing the input in isn't defined. Then, when I activate the "Start Flipping" button, the animation does not start, and I receive a second traceback error: "command=lambda : animation(count))NameError: name 'animation' is not defined Please see the code and traceback error below."

Thanks in advance for the help and consideration! :) (PS: Don't worry about the naming conventions; this snippet is part of a larger program that doesn't affect this code's functionality, and I have tried using tkinter.Tk() as an alternative to tkinter.Toplevel() to no avail).


import tkinter 
from tkinter import * 
from tkinter import ttk
from tkinter import messagebox
import time
import os
import PIL
from PIL import ImageTk
import glob
import random


root_2 = tkinter.Toplevel()
root_2.geometry('800x800')
root_2.title("Determination of Turn Order")


''' The code below is for implementing a window widget for:
    
    1) Displaying message to user that will call coin flip 
    2) Prompting user to call coin flip
    3) Prompting user to run coin flip simulation
    4) Displaying message to users to reflect coin flip outcome
    5) Displaying message to users to reflect turn order

'''

player1 = "Justin"
player2 = "Jaclyn"

# Define Canvas widget to overlay entry and label widgets on turn order window

canvas_3 = tkinter.Canvas(root_2,width=800,height=800)
canvas_3.pack(expand = tkinter.TRUE, fill = tkinter.BOTH) # Set width and height parameters
 
# Create Label widget to display message to user that will call coin flip
   
user_coin_call_label = tkinter.Label(canvas_3, text = player1 + " Will Call The Coin Flip", font=('calibre',30,'bold'))
user_coin_call_label.pack()
user_coin_call_label.place(x=100,y=0)

# # Create dialogue-button widget to read in text from user

# Declare "StringVar" object for storing coin text input

global coin_guess, coin_guess_obj
coin_guess_obj = tkinter.StringVar()

# Define function that will read in coin guess from Entry widget

def input_guess():
    
    ''' This function reads in coin guess from Entry widget'''
    
    global coin_guess, coin_guess_obj
    coin_guess = coin_guess_obj.get()
    #coin_guess_obj.set("")
    #root.destroy()

def destroy_turn_order_win():
    
    root_2.destroy()

# Define label for prompting player to input coin flip gues

user_coin_input_label = tkinter.Label(canvas_3, text = player1 + ", please input coin flip guess (H/T)")
#user_coin_input_label.pack()
user_coin_input_label.place(x=0,y=50)

# Define entry field for coin flip guess input using Entry widget

user_coin_input_entry = tkinter.Entry(canvas_3, textvariable = coin_guess_obj, width=20)
#user_coin_input_entry.pack()
user_coin_input_entry.place(x=220, y=50)

# Define button for submitting coin flip guess using Button widget

submit_guess_button=tkinter.Button(canvas_3, text="Submit", command=input_guess)
#submit_guess_button.pack()
submit_guess_button.place(x=0, y=75)

# Define label for prompting player to run and stop coin flip simulation: 
    
start_stop_coin_sim_label = tkinter.Label(canvas_3, text = player1 + ", please start and stop coin a flip simulation using the buttons below")
#start_stop_coin_sim_label.pack()
start_stop_coin_sim_label.place(x=0, y=100)

# Load image frames of coin toss gif

filename = 'coin_toss_1.gif'
file_opn = PIL.Image.open(filename)
frame_num = file_opn.n_frames

im = [ImageTk.PhotoImage(file=filename, format = f'gif -index {i}') for i in range(frame_num)]

global coin_frame, coin_outcome, anim
anim = None
count = 0

def animation(count):
    
    ''' This function animates the gif by displaying successive frames
    on a label widget '''
    
    global anim, coin_frame
    im2 = im[count]
    gif_label.configure(image=im2)
    print(count)
    # self.coin_frame = count to store frame as data member and associate with known coin outcome
    coin_frame = count
    
    count += 1
    
    if count == frame_num: 
        
        count = 0
    
    anim = canvas_3.after(0, lambda : animation(count))

def set_coin_outcome():
    
    ''' This function compares the coin frame number of the last frame 
    loaded in the animation() call to relationships between frame numbers
    and associated coin outcomes to store the coin toss outcome '''
    
    # Place holder to test stop_animation() call of set_coin_outcome:
    
    global coin_frame, coin_outcome  
    
    #print("heads")
    
    if (coin_frame == 0):
  
        
        # heads outcome
        
        coin_outcome = "H"
     
    elif (coin_frame == 1):
   
        
        # tails outcome
        coin_outcome = "T"
    
    elif ((coin_frame %2) == 1):
   
        
        # tails outcome
        coin_outcome = "T"
        
    else:
        
        # heads outcome
        
        #self.coin_outcome = heads
        coin_outcome = "H"
        
    
def stop_animation():
    
    ''' This function terminates the "animation()" function 
    which stops the frame animation of the gif '''
    
    global anim, coin_frame, coin_outcome

    canvas_3.after_cancel(anim)
    
    set_coin_outcome()

im_base = [ImageTk.PhotoImage(file=filename, format = f'gif -index {0}')]

gif_label = tkinter.Label(canvas_3, image=im_base)
#gif_label.pack()
gif_label.place(x = 240, y = 300)

start_button = tkinter.Button(canvas_3, text="Start Flipping", command=lambda : animation(count))
#start_button.pack()
start_button.place(x=350, y=250)

stop_button = tkinter.Button(canvas_3, text="Stop Flipping", command=stop_animation)
#stop_button.pack()
stop_button.place(x=350, y=275)

#coin_outcome = "H" # Placeholder

if (coin_guess == "H" and coin_outcome == "H"):
    
    turn_order_label = tkinter.Label(canvas_3, text = player1 + ", you will have the first turn")
    #turn_order_label.pack()
    turn_order_label.place(x=240, y=500)

elif(coin_guess == "T" and coin_outcome == "T"):
    
    turn_order_label = tkinter.Label(canvas_3, text = player1 + ", you will have the first turn")
    #turn_order_label.pack()
    turn_order_label.place(x=240, y=500)

else: 
    
    turn_order_label = tkinter.Label(canvas_3, text = player2 + ", you will have the first turn")
    #turn_order_label.pack()
    turn_order_label.place(x=240, y=500)
    

continue_game_button=tkinter.Button(canvas_3, text="Continue Game", command=destroy_turn_order_win)
#continue_game_button.pack()
continue_game_button.place(x=300,y=550)

canvas_3.mainloop()

'''

Traceback Error 1: 

Exception in Tkinter callback
Traceback (most recent call last):
  File "/Applications/anaconda3/lib/python3.8/tkinter/__init__.py", line 1883, in __call__
    return self.func(*args)
  File "/Users/jcam98/Desktop/Programming_Applications/Python/Practice_Scripts/tkinter_gui_tutorial.py", line 348, in input_guess
    coin_guess = coin_guess_obj.get()
NameError: name 'coin_guess_obj' is not defined


Traceback Error 2: 


Exception in Tkinter callback
Traceback (most recent call last):
  File "/Applications/anaconda3/lib/python3.8/tkinter/__init__.py", line 1883, in __call__
    return self.func(*args)
  File "/Users/jcam98/Desktop/Programming_Applications/Python/Practice_Scripts/tkinter_gui_tutorial.py", line 474, in <lambda>
    start_button = tkinter.Button(canvas_3, text="Start Flipping", command=lambda : animation(count))
NameError: name 'animation' is not defined

'''
[Current state of GUI][1]


  [1]: https://i.stack.imgur.com/Em0P5.png
0 Answers
Related