0

The code below is what I'm referencing from tkinter import *

root = Tk()

#Variables
answer = "Enter Answer"

data = ""

#Functions
def function():
    data = e.get()
    while data == "":
        if data == 5:
            answer = "Correct"
        if data != 5:
            answer = "Incorrect"
    print(answer)


top = Label(root, text = "Test")
top.pack()

e = Entry(root)
e.pack()
e.focus_set()

b = Button(root, text = "Enter", command = function)
b.pack()

check = Label(root, text = answer)
check.pack()

mainloop()

I can't seem to update the label widget (name 'check'). I want to be able to update it based checking a condition, but I can't get it to work. I placed the 'print(answer)' line to check the variable, but I get the error:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python34\lib\tkinter\__init__.py", line 1533, in __call__
    return self.func(*args)
  File "G:/Portable Apps/Portable Python 3.2.5.1/Documents/TEST.py", line 22, in function
    print(answer)
UnboundLocalError: local variable 'answer' referenced before assignment

This occurs when I run the program, type a value, then select the enter button.

Kai Brennan
  • 1
  • 1
  • 1

1 Answers1

1

Your answer variable is not defined within the function's scope. To accomplish this in the simplest way I suggest you use a class to hold all of the widgets from your UI.

from tkinter import *

class Window():

    def __init__(self, root):

        self.top = Label(root, text = "Test")
        self.top.pack()

        self.e = Entry(root)
        self.e.pack()
        self.e.focus_set()

        self.b = Button(root, text = "Enter", command = self.function)
        self.b.pack()

        self.answer = StringVar()
        self.answer.set("Enter answer")

        self.check = Label(root, text = self.answer.get(), textvariable = self.answer)
        self.check.pack()

    #Functions
    def function(self):

        data = self.e.get()

        if data == "5":
            self.answer.set("Correct")
        else:
            self.answer.set("Incorrect")

root = Tk()
w = Window(root)
root.mainloop()

Additionally, since widget command's work as callbacks, you won't need to use a while loop to accomplish what you want. Just put the if/else check, as I have done, and every time you click the button it will check again.

I also changed your answer variable to be an instance of StringVar(). This is a type of Tkinter variable specifically designed to accomplish what you're trying to do. I can then use the config option textvariable = self.answer to allow the label to update whenever the StringVar is changed. To access the text of the StringVar you must call self.answer.get(); to change the data you call self.answer.set("text") like I have done within function.

Finally, since your Entry self.e is an instance of StringVar as well, I had to change your if condition to if data == "5": as data will be a String rather than an int.

maccartm
  • 2,035
  • 14
  • 23