I'm trying to simulate a lottery and have a little problem with my functions. Here's what I'm trying to do:
- run window1()
- window1() --> destroy_window1() --> window2()
- window2() --> destroy window2 or retry() --> window1()
The error occurs when I reach destroy_window1(), where i get the following message: "NameError: name 'e1' is not defined". How can I solve this problem?
I've read that you should pre-define the variables outside the functions. So, I tried to just put e1 = 1 etc., but then i get the message: "AttributeError: 'int' object has no attribute 'get'". Since it's an entry, I don't know how to pre-define it.
from tkinter import*
import random
Part1 = list(range(1,51))
Part2 = list(range(1,11))
Numbers = [0]*7
for n in range (5):
Number = random.choice(Part1)
Position = Part1.index(Number)
del Part1[Position]
Numbers[n] = Number
for i in range (2):
Number = random.choice(Part2)
Position = Part2.index(Number)
del Part2[Position]
Numbers[5+i] = Number
print (Numbers)
def destroy_window1():
global Guess
Guess = [e1.get(), e2.get(), e3.get(), e4.get(), e5.get(), e6.get(), e7.get()]
master1.destroy()
window2()
def retry():
master2.destroy()
window1()
def window1():
master1 = Tk()
master1.title('Lottery')
Label(master1, text="Guess numbers:").grid(row=0)
e1 = Entry(master1, width=2)
e2 = Entry(master1, width=2)
e3 = Entry(master1, width=2)
e4 = Entry(master1, width=2)
e5 = Entry(master1, width=2)
e6 = Entry(master1, width=2)
e7 = Entry(master1, width=2)
e1.grid(row=0, column=1, padx=5)
e2.grid(row=0, column=2, padx=5)
e3.grid(row=0, column=3, padx=5)
e4.grid(row=0, column=4, padx=5)
e5.grid(row=0, column=5, padx=5)
e6.grid(row=0, column=7, padx=5)
e7.grid(row=0, column=8, padx=5)
master1.grid_columnconfigure(6, minsize=20) # Creates an empty column (nr. 6) with width 20
Button(master1, text='OK', command=destroy_window1).grid(row=3, column=3, sticky=W, pady=5)
master1.mainloop()
def window2():
master2 = Tk()
master2.title('Check results')
Label(master2, text="Drawn numbers:").grid(row=0, column=0, sticky=W)
Label(master2, text="Your numbers:").grid(row=1, column=0, sticky=W)
for n in range (7):
Label(master2, text=Numbers[n]).grid(row=0, column=n+1, sticky=W, padx=5)
if str(Numbers[n]) == Guess[n]:
Label(master2, text=Guess[n], bg="green").grid(row=1, column=n+1, sticky=W, padx=5)
else:
Label(master2, text=Guess[n], bg="red").grid(row=1, column=n+1, sticky=W, padx=5)
Button(master2, text='Quit', command=master2.destroy).grid(row=3, column=3, sticky=W, pady=5)
Button(master2, text='Retry', command=retry).grid(row=3, column=4, sticky=W, pady=5)
master2.mainloop ()
window1()
I can't vote up yet, thanks in advance!
The problem is that the
destroy_window1()
function doesn't know about thee1
variable, becausee1
is defined within thewindow1()
function (and its not global).A simple fix is to put all the e variables into a
list
and pass thatlist
as an argument to thedestroy_window1()
function. Make the list with a simple for loop, this not only solves your problem, but it also makes your code cleaner, easier to read, and easier to change it's functionality in future.Like so:
Part of this solution involves a
lambda
function. This is because (as you may have noticed) the command option normally can't take arguments for the functions. The use of alambda
functions makes this possible. (Read up on Lambda Functions Here)When you set
e1=1
you are setting the variablee1
to 1 but the.get()
function doesn't apply to an integer because the function has not been defined.