Tkinter GUI Error

F

fluttershy363

Inside the function is where I am having the problem, I am trying to get it to delete the label so that it may then replace it with a shorter text.
Here is the full code:




from tkinter import *
import random
main = Tk()
main.title("Crack the Code")

def check1():
entry = entry1var.get()
if entry == num1:
labelent1.destroy()
labelent1 = Label(main, text="Correct!",fg="green").grid(row = 0, column = 3)
elif entry > num1:
labelent1.destroy()
labelent1 = Label(main, text="Too Big",fg="red").grid(row = 0, column = 3)
elif entry < num1:
labelent1.destroy()
labelent1 = Label(main, text="Too Small",fg="red").grid(row = 0, column = 3)




global num1
global num2
global num3
num1 =str(random.randint(10,99))
num2 =str(random.randint(10,99))
num3 =str(random.randint(10,99))
mastercode = num1+num2+num3


entry1var = StringVar()
entry2var = StringVar()
entry3var = StringVar()


number1 = Label(main, text="Number 1").grid(row = 0, column = 0)
number2 = Label(main, text="Number 2").grid(row = 1, column = 0)
number3 = Label(main, text="Number 3").grid(row = 2, column = 0)
entry1 = Entry(main, textvariable=entry1var).grid(row=0,column=1)
entry2 = Entry(main, textvariable=entry2var).grid(row=1,column=1)
entry3 = Entry(main, textvariable=entry3var).grid(row=2,column=1)
button1 = Button(main, text="Try Number",command=check1).grid(row=0,column=2)
button2 = Button(main, text="Try Number").grid(row=1,column=2)
button3 = Button(main, text="Try Number").grid(row=2,column=2)

labelent1 = Label(main, text="Waiting for Input").grid(row = 0, column = 3)
labelent2 = Label(main, text="Waiting for Input").grid(row = 1, column = 3)
labelent3 = Label(main, text="Waiting for Input").grid(row = 2, column = 3)



mastercodelabel= Label(main, text="Enter master code below:").grid(row=3,column=1)
mastercodeentry= Entry(main).grid(row=4,column=1)
mastercodebutton= Button(main,text="Enter").grid(row=4,column=2)




#main.config(menu=menubar)
main.mainloop()




And this is the error displayed when clicking on button1:

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
return self.func(*args)
File "C:/Users/User/Desktop/Programming/Tkinter/Tkinter.py", line 15, in check1
labelent1.destroy()
UnboundLocalError: local variable 'labelent1' referenced before assignment


Thanks, Lewis.
 
L

Lewis Wood

When I try to use the labelent1.configure, it greets me with an error:
AttributeError: 'NoneType' object has no attribute 'configure'

I changed the labelent's to global. Don't suppose you know why?
Also how would I go about using an object for the entire window. I am still a Novice at Tkinter and Python but can make my way around it.
 
P

Peter Otten

Inside the function is where I am having the problem, I am trying to get
it to delete the label so that it may then replace it with a shorter text.
Here is the full code:
def check1():
entry = entry1var.get()
if entry == num1:
labelent1.destroy()
labelent1 = Label(main, text="Correct!",fg="green").grid(row = 0,
column = 3)
elif entry > num1:
labelent1.destroy()
labelent1 = Label(main, text="Too Big",fg="red").grid(row = 0,
column = 3)
elif entry < num1:
labelent1.destroy()
labelent1 = Label(main, text="Too Small",fg="red").grid(row = 0,
column = 3)
And this is the error displayed when clicking on button1:

Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1475, in __call__
return self.func(*args)
File "C:/Users/User/Desktop/Programming/Tkinter/Tkinter.py", line 15, in
check1
labelent1.destroy()
UnboundLocalError: local variable 'labelent1' referenced before assignment


Thanks, Lewis.

Kudos, your problem description is very clear!

Your post would be perfect, had you reduced the number of Labels from three
to one ;)

The error you are seeing has nothing to do with the GUI. When you assign to
a name inside a function Python determines that the name is local to that
function. A minimal example that produces the same error is
.... print(a)
.... a = "local"
....Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in test
UnboundLocalError: local variable 'a' referenced before assignment

The name `a` passed to print() references the local `a` which is not yet
defined. A possible fix is to tell Python to reference the global `a`
.... global a
.... print(a)
.... a = "local"
....'local'

However, in the case of your GUI code you should not destroy and create
Label instances -- it is more efficient (and easier I think) to modify the
Label's text:

(1) working demo with 'global' -- don't do it that way:

from tkinter import *

main = Tk()

def check1():
global labelent1
labelent1.destroy()
labelent1 = Label(main, text="Correct!", fg="green")
labelent1.grid(row = 0, column = 3) # must be a separate statement as
# grid() returns None

Button(main, text="Try Number", command=check1).grid(row=0, column=2)
labelent1 = Label(main, text="Waiting for Input")
labelent1.grid(row=0, column=3) # must be a separate statement as
# grid() returns None

main.mainloop()


(2) The way to go, modify the label text instead of replacing it:

from tkinter import *

main = Tk()

def check1():
labelent1.configure(text="Correct!", fg="green")

Button(main, text="Try Number", command=check1).grid(row=0, column=2)
labelent1 = Label(main, text="Waiting for Input")
labelent1.grid(row=0, column=3)

main.mainloop()
global num1

By the way, global declarations on the module level have no effect.
 
D

Dennis Lee Bieber

Inside the function is where I am having the problem, I am trying to get it to delete the label so that it may then replace it with a shorter text.
Here is the full code:
global num1
global num2
global num3

These do not do what you think they do...

"global" is used INSIDE of functions (def) to specify that references
to the name on the inside MUST access the module level name.

Note: read-only access does not need "global"; only bindings to the
name (assignments) have to have the "global" otherwise they define a local
name.
 
R

Rick Johnson

labelent1 = Label(main, text="Correct!",fg="green").grid(row = 0, column = 3)

[snip]

UnboundLocalError: local variable 'labelent1' referenced before assignment

Observe the following interactive session and prepare to be enlightened.

## INCORRECT ##
py> from Tkinter import *
py> root = Tk()
py> label = Label(root, text="Blah").pack()
py> type(label)
<type 'NoneType'>

## CORRECT ##
py> label = Label(root, text="Blah")
py> label.pack()
py> label
<Tkinter.Label instance at 0x027C69B8>
py> type(label)
<type 'instance'>

## ANY QUESTIONS? ##
py> help()
 
C

Chris Angelico

entry = entry1var.get()
if entry == num1:
elif entry > num1:
elif entry < num1:

num1 =str(random.randint(10,99))
num2 =str(random.randint(10,99))
num3 =str(random.randint(10,99))
mastercode = num1+num2+num3

Be careful of code like this. You've specified that your three parts
range from 10 through 99, so this will work as long as the user knows
this and enters exactly two digits. Doing inequality comparisons on
strings that represent numbers will work as long as they're the same
length, but if the lengths vary, the string comparisons will start at
the beginning - not what most people will expect. These are all true:

"2" > "10"
"3.14159" > "2,000,000"
"42" < "Life, the universe, and everything"
"00012" < "12"

If your intention is to have a six-digit number, you could simply ask
for one, and then format the pieces accordingly:

num = random.randint(1,999999)
num_str = "%06d" % num

You can then slice up num_str as needed (it'll have leading zeroes if
it needs them), or you can do numerical comparisons against num
itself.

ChrisA
 
L

Lewis Wood

I cannot say how grateful I am to find such a community willing to help <3 Thanks to everyone posting, learned a lot of new stuff :) Never knew you could just bring a local var into a def block using global inside of the function. Again, thanks for taking your time to help out newbies to programmingsuch as myself.
 
L

Lewis Wood

Also anyone know how to create an entry box for Tkinter where you can only enter in 2 digits?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,790
Messages
2,569,637
Members
45,346
Latest member
EstebanCoa

Latest Threads

Top