Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #63854 > unrolled thread
| Started by | fluttershy363@gmail.com |
|---|---|
| First post | 2014-01-13 10:49 -0800 |
| Last post | 2014-01-14 22:33 +0100 |
| Articles | 11 — 7 participants |
Back to article view | Back to comp.lang.python
Tkinter GUI Error fluttershy363@gmail.com - 2014-01-13 10:49 -0800
Re: Tkinter GUI Error Lewis Wood <fluttershy363@gmail.com> - 2014-01-13 10:51 -0800
Re: Tkinter GUI Error Christian Gollwitzer <auriocus@gmx.de> - 2014-01-13 20:03 +0100
Re: Tkinter GUI Error Lewis Wood <fluttershy363@gmail.com> - 2014-01-13 11:21 -0800
Re: Tkinter GUI Error Peter Otten <__peter__@web.de> - 2014-01-13 20:36 +0100
Re: Tkinter GUI Error Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2014-01-13 20:39 -0500
Re: Tkinter GUI Error Rick Johnson <rantingrickjohnson@gmail.com> - 2014-01-13 18:47 -0800
Re: Tkinter GUI Error Chris Angelico <rosuav@gmail.com> - 2014-01-14 14:12 +1100
Re: Tkinter GUI Error Lewis Wood <fluttershy363@gmail.com> - 2014-01-14 11:11 -0800
Re: Tkinter GUI Error Lewis Wood <fluttershy363@gmail.com> - 2014-01-14 13:27 -0800
Re: Tkinter GUI Error Christian Gollwitzer <auriocus@gmx.de> - 2014-01-14 22:33 +0100
| From | fluttershy363@gmail.com |
|---|---|
| Date | 2014-01-13 10:49 -0800 |
| Subject | Tkinter GUI Error |
| Message-ID | <1ab2aa93-1ba6-48b0-a5f4-5fb05cb523d1@googlegroups.com> |
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.
[toc] | [next] | [standalone]
| From | Lewis Wood <fluttershy363@gmail.com> |
|---|---|
| Date | 2014-01-13 10:51 -0800 |
| Message-ID | <7b21d69d-7272-4e7b-ab85-621f044d205c@googlegroups.com> |
| In reply to | #63854 |
Forgot to mention I am using Python 3.3.3
[toc] | [prev] | [next] | [standalone]
| From | Christian Gollwitzer <auriocus@gmx.de> |
|---|---|
| Date | 2014-01-13 20:03 +0100 |
| Message-ID | <lb1dae$tbm$1@dont-email.me> |
| In reply to | #63854 |
Am 13.01.14 19:49, schrieb fluttershy363@gmail.com:
>
> 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)
This is the wrong way to do it. Yes, in principle you could remove the
label and put a new one there; but it's much better to just change the
text of it by means of either
labelent1.configure(text="New text ")
or by linking a variable with the label variable at the setup time
somestringvar = StringVar("initial text")
Label(main, textvariable=somestringvar)
and then change that variable
somestringvar.set("New text")
Both of these don't solve the error, though; it has nothing to do with
Tk, you just did not make labelent1 global. However, I strongly advise
to use an object for the entire window, where you make this labelent1 an
instance variable (put into self).
Christian
[toc] | [prev] | [next] | [standalone]
| From | Lewis Wood <fluttershy363@gmail.com> |
|---|---|
| Date | 2014-01-13 11:21 -0800 |
| Message-ID | <acc5ef7f-a408-42ca-9b67-c94950cfe571@googlegroups.com> |
| In reply to | #63856 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Date | 2014-01-13 20:36 +0100 |
| Message-ID | <mailman.5426.1389641835.18130.python-list@python.org> |
| In reply to | #63854 |
fluttershy363@gmail.com wrote:
> 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
>>> a = "global"
>>> def test():
... print(a)
... a = "local"
...
>>> test()
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`
>>> a = "global"
>>> def test():
... global a
... print(a)
... a = "local"
...
>>> test()
global
>>> a
'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.
[toc] | [prev] | [next] | [standalone]
| From | Dennis Lee Bieber <wlfraed@ix.netcom.com> |
|---|---|
| Date | 2014-01-13 20:39 -0500 |
| Message-ID | <mailman.5434.1389663555.18130.python-list@python.org> |
| In reply to | #63854 |
On Mon, 13 Jan 2014 10:49:07 -0800 (PST), fluttershy363@gmail.com declaimed
the following:
>
>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:
>
<snip>
>
>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.
--
Wulfraed Dennis Lee Bieber AF6VN
wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2014-01-13 18:47 -0800 |
| Message-ID | <e8e5c10d-67c8-49ed-a9ce-f6dbb177039b@googlegroups.com> |
| In reply to | #63854 |
On Monday, January 13, 2014 12:49:07 PM UTC-6, Lewis Wood wrote: > 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()
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-01-14 14:12 +1100 |
| Message-ID | <mailman.5435.1389669132.18130.python-list@python.org> |
| In reply to | #63854 |
On Tue, Jan 14, 2014 at 5:49 AM, <fluttershy363@gmail.com> wrote: > 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
[toc] | [prev] | [next] | [standalone]
| From | Lewis Wood <fluttershy363@gmail.com> |
|---|---|
| Date | 2014-01-14 11:11 -0800 |
| Message-ID | <3f7e442e-b86d-45c9-bd70-52c6abcca549@googlegroups.com> |
| In reply to | #63870 |
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 programming such as myself.
[toc] | [prev] | [next] | [standalone]
| From | Lewis Wood <fluttershy363@gmail.com> |
|---|---|
| Date | 2014-01-14 13:27 -0800 |
| Message-ID | <95e61d6c-5626-4d29-9dda-98e1bcb38546@googlegroups.com> |
| In reply to | #63925 |
Also anyone know how to create an entry box for Tkinter where you can only enter in 2 digits?
[toc] | [prev] | [next] | [standalone]
| From | Christian Gollwitzer <auriocus@gmx.de> |
|---|---|
| Date | 2014-01-14 22:33 +0100 |
| Message-ID | <lb4afa$4dp$1@dont-email.me> |
| In reply to | #63944 |
Am 14.01.14 22:27, schrieb Lewis Wood: > Also anyone know how to create an entry box for Tkinter where you can only enter in 2 digits? > You must use a validator to achieve this. This is a more advanced topic though. A validator is a function that is called whenever the user keys something in - even by copy/pasting - and has to decide, whether this change is accepted or not. It is relatively easy to annoy your users if the validator is not written carefully. For instance, you must always accept th eempty string, otherwise the users won't be able to delete everything - very annoying behaviour. See for example this SO question http://stackoverflow.com/questions/4140437/python-tkinter-interactively-validating-entry-widget-content Christian
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web