How to check if only one statement equals 0? - python

I got some trouble with finding the matching if-statement to check if only one entry equals 0 of 3.
Here's the code:
def thanx(self):
if len(self.e.get()) == 0:
messagebox.showerror("Error", "Please enter affordable infos")
self.boo = False
else:
messagebox.showinfo("Submition done", "Thank you")
self.boo = True
It is only checking if my variable e equals 0, but i actually got 2 more entries. I know i could check every single one individually, however there has to be an easier way of doing this.
Im using "tkinter" btw, but this shouldnt be too much important.
I tried it with or but this isn't working or I'm doing it wrong.
(Also tried to solve this with lambda, but again just errors...)
Maybe someone can help me there...
Edit:
I might have explained this a bit confusing, I'll add the rest of the code here that you can understand this better:
from tkinter import Tk, Label, Entry, Button, W
from tkinter import messagebox
class MyForm:
def thanx(self):
if len(self.e.get()) == 0:
messagebox.showerror("Error", "Please enter affordable infos")
self.boo = False
else:
messagebox.showinfo("Submition done", "Thank you")
self.boo = True
def callback(self):
#print("Name: %s\nPassword: %s\nEmail: %s" % (self.e.get(), self.e2.get(),self.e3.get()))
if self.boo:
f = open("PrivatData.txt", "w+")
f.write("Name: %s\nPassword: %s\nEmail: %s" % (self.e.get(), self.e2.get(),self.e3.get()))
def __init__(self):
self.root = Tk()
self.root.title("Your privat details")
Label(self.root, text="Your Name").grid(row = 0, padx = 12, pady=5)
Label(self.root, text="Password").grid(row=1, padx=12, pady=5)
Label(self.root, text="Email").grid(row=2, padx=12, pady=5)
self.e = Entry(self.root)
self.e2 = Entry(self.root)
self.e3= Entry(self.root)
self.e.grid(row=0,column=1,columnspan=2)
self.e2.grid(row=1, column=1, columnspan=2)
self.e3.grid(row=2, column=1, columnspan=2)
self.e.focus_set()
self.show= Button(self.root, text="Submit", command=lambda:[self.thanx(),self.callback()])
self.quit = Button(self.root,text="Quit", command = self.root.quit)
self.show.grid(row=3, column=1, pady=4)
self.quit.grid(row=3, column=2, sticky = W, pady=4)
self.root.geometry("230x140")
self.root.configure(background= "#65499c")
self.root.mainloop()
if __name__ == "__main__":
app= MyForm()

Use any:
if any((len(self.e.get().strip())==0,len(self.e2.get().strip())==0,len(self.e2.get().strip())==0)):
do stuff to say that user did not input all fields
else:
do stuff to say that user inputted all fields
So full code:
from tkinter import Tk, Label, Entry, Button, W
from tkinter import messagebox
class MyForm:
def thanx(self):
if any((len(self.e.get().strip())==0,len(self.e2.get().strip())==0,len(self.e2.get().strip())==0)):
messagebox.showerror("Error", "Please enter affordable infos")
self.boo = False
else:
messagebox.showinfo("Submition done", "Thank you")
self.boo = True
def callback(self):
#print("Name: %s\nPassword: %s\nEmail: %s" % (self.e.get(), self.e2.get(),self.e3.get()))
if self.boo:
f = open("PrivatData.txt", "w+")
f.write("Name: %s\nPassword: %s\nEmail: %s" % (self.e.get(), self.e2.get(),self.e3.get()))
def __init__(self):
self.root = Tk()
self.root.title("Your privat details")
Label(self.root, text="Your Name").grid(row = 0, padx = 12, pady=5)
Label(self.root, text="Password").grid(row=1, padx=12, pady=5)
Label(self.root, text="Email").grid(row=2, padx=12, pady=5)
self.e = Entry(self.root)
self.e2 = Entry(self.root)
self.e3= Entry(self.root)
self.e.grid(row=0,column=1,columnspan=2)
self.e2.grid(row=1, column=1, columnspan=2)
self.e3.grid(row=2, column=1, columnspan=2)
self.e.focus_set()
self.show= Button(self.root, text="Submit", command=lambda:[self.thanx(),self.callback()])
self.quit = Button(self.root,text="Quit", command = self.root.quit)
self.show.grid(row=3, column=1, pady=4)
self.quit.grid(row=3, column=2, sticky = W, pady=4)
self.root.geometry("230x140")
self.root.configure(background= "#65499c")
self.root.mainloop()
if __name__ == "__main__":
app= MyForm()

I am assuming that at the moment you are checking if some string element equals 0.
For example
e = 'abc'
len(e) == 3 # True
l = []
len(l) == 0 # True
If you want to check if your string variable is 0 then simply:
if not self.e.get():
messagebox.showerror("Error")
self.boo = False

You may try this:
if len(self.e.get()) == 0 or len(self.e2.get()) == 0 or len(self.e3.get()) == 0:
messagebox.showerror("Error", "Please enter affordable infos")
self.boo = False
else:
messagebox.showinfo("Submition done", "Thank you")
self.boo = True
Since you have 3 variables, there's no way to check them all 'in batch' unless you build a data structure containing them and then check some conditions on that data structure. However, it does not give any advantage. If you add a new variable, say e4, you still have to add it manually to the the data structure.

To ensure that all three textboxes are not empty in one if statement, you can use the following:
if "" in [self.e.get().strip(), self.e2.get().strip(), self.e3.get().strip()]:
messagebox.showerror("Error", "Please enter affordable infos")
self.boo = False
else:
messagebox.showinfo("Submition done", "Thank you")
self.boo = True
This is a short and neat way to write what you are trying to do. This works because entry widgets will return "" if they are empty, and self.e.get().strip() makes the text returned empty (.strip() removes all whitespace at both the start and the end of the string) if it is just whitespace (" ", \t, n, etc...).
It is better to check the contents of the string rather than the length of it, because a box with just whitespace in it will not return 0, as shown below.
>>> len(" ")
1
>>> len("")
0
>>> len("\t")
1

Related

Can't get the value of a radio-button in Python/Tkinter

I'm writing a simple unit converter where the user can pick which units they want to convert from two options. I'm using radio-buttons for the choice, but can't seem to get the value of the chosen one to work in the conditions at the bottom of the program.
I tried several solutions suggested here on stack overflow, but none of them worked. At one point, I got the selected() to print the value of the button, but it still didn't work in the condition. Am I missing something obvious here?
Please, note, the converter is not finished yet, there is still some more polishing to do after this issue is solved.
from tkinter import *
window = Tk()
window.title("Unit converter")
window.minsize(width=300, height=300)
window.config(padx=50, pady=50)
def lbs_kgs():
user_input = float(unit_A1.get())
result = round((user_input / 2.2046), 2)
unit_B1.config(text= f"{result}")
def mil_km():
user_input = float(unit_A1.get())
result = round((user_input * 1.6), 2)
unit_B1.config(text= result)
def selected():
return radio_state.get()
intro_label = Label(text = "What units would you like to convert?")
intro_label.grid(column=0, row=0, columnspan=4, pady=10)
radio_state = StringVar()
radiobutton1 = Radiobutton(text="Pounds to kilograms", value="pk", variable=radio_state, command=selected)
radiobutton2 = Radiobutton(text="Miles to kilometers", value="mk", variable=radio_state, command=selected)
radiobutton1.grid(column=0, row=1, columnspan=4)
radiobutton2.grid(column=0, row=2, columnspan=4)
instructions_label = Label(text = "Enter the number:")
instructions_label.grid(column=0, row=3, columnspan=4, pady=10)
unit_A1 = Entry(width=5)
unit_A1.grid(column=1, row=4, sticky="e")
unit_A1_label = Label(text = "unit A1")
unit_A1_label.grid(column=2, row=4, sticky="w")
equal_label = Label(text = "is equal to")
equal_label.grid(column=1, row=5, sticky="e")
unit_B1 = Label(text = "0")
unit_B1.grid(column=2, row=5, sticky="w")
unit_B1_label = Label(text = "result unit")
unit_B1_label.grid(column=3, row=5, sticky="w")
button = Button(text="Calculate")
button.grid(column=0, row=6, columnspan=4, pady=10)
if selected() == "pk":
button.config(command=lbs_kgs)
elif selected() == "mk":
button.config(command=mil_km)
window.mainloop()
Move the if/else check into the selected function so the conditions can be checked each time the selection changes
def selected():
selection = radio_state.get()
if selection == "pk":
button.config(command=lbs_kgs)
elif selection == "mk":
button.config(command=mil_km)
In line 29 should be radio_state = StringVar(window, '1'). Without this when executed both radiobutton are on, but that not right.
def selected():
if (selection := radio_state.get()) == "pk":
button.config(command=lbs_kgs)
elif selection == "mk":
button.config(command=mil_km)
Output:
Output pound to Kilograms:
Output Miles to Kilometers:

My code wont work, is there some logical error here?

Can someone help me, Im trying to make a banking program and when i try to login and enter the correct details, it still says "notok". I put in some values for testing purposes and it just wont work and it would always print notok. Please help
import tkinter as tk
from tkinter import messagebox
import random
def checklog(ac,pin):
if (ac==1) and (pin==2):
print("ok")
else:
print("notok")
def exitwin(master):
master.destroy()
def acc_no(master):
acc_no.acc = random.randrange(1000000000,9999999999)
messagebox.showinfo("Account Number", acc_no.acc)
return
def openac():
op = tk.Tk()
op.title("Open a account")
op.minsize(500,500)
op.configure(bg='gray90')
l1 = tk.Label(op, text="Full Name")
l1.grid(row=0, column=2)
openac.name = tk.Entry(op)
openac.name.grid(row=0, column=3)
l2 = tk.Label(op, text="Enter Starting Deposit")
l2.grid(row=1, column=2)
openac.fun = tk.Entry(op)
openac.fun.grid(row=1, column=3)
l3 = tk.Label(op, text="Enter your pin")
l3.grid(row=2, column=2)
openac.pin = tk.Entry(op, show="*")
openac.pin.grid(row=2, column=3)
sub = tk.Button(op, text="Submit", command=lambda: [acc_no(op), login(), exitwin(op)])
sub.grid(row=3, column=1)
op.bind("<Return>", lambda x:[dep(op, e1.get(),e2.get(), e3.get()), acc_no(op), login(op, e1.get(), e2.get(), e3.get()), exitwin(op)])
return
def login():
log = tk.Tk()
log.title("Login")
log.minsize(500,500)
l1 = tk.Label(log, text="Enter your account number")
l1.grid(row=0, column=0)
e1 = tk.Entry(log)
e1.grid(row=0, column=1)
l2 = tk.Label(log, text="Enter your pin")
l2.grid(row=1, column=0)
e2 = tk.Entry(log)
e2.grid(row=1, column=1)
sub = tk.Button(log, text="Sumbit", command=lambda: checklog(e1.get(), e2.get()))
sub.grid(row=1, column=2)
return
log.mainloop()
def dep(master, name, fund, pin):
x=0
def draw():
x=0
def mainmenu():
mm = tk.Tk()
mm.title("Bank")
mm.minsize(400,400)
mm.configure(bg='gray70')
l1 = tk.Label(mm, text="HELLO")
l1.config(font=("Courier", "25"))
l1.grid(row=0)
b1 = tk.Button(mm, text="Sign Up", command=openac)
b1.grid(row=2)
b2 = tk.Button(mm, text="Log In", command=lambda: login(mm))
b2.grid(row=3)
mm.mainloop()
mainmenu()
You're checking if the .get()'s of your text boxes are equal to an integer, but you have not converted them into an integer, they are a string by default.
def checklog(ac, pin):
if ac == "1" and pin == "2":
print("ok")
else:
print("not ok")
Best practice dictates that you convert the value to an integer yourself and throw an error when it cannot be converted. Something that tells the user their account number or pin failed validation as it is not a number.
The values that you pass to checklog come from calling .get on a tk.Entry, which produces a string (it must do this, because you could type whatever text you like, not just ones that look like numbers). The comparison ac==1 fails because ac is a string. You must convert the value yourself, and handle the case when a non-number is typed.
This is not really a Tkinter question; it's the same problem that beginners have all the time with input().

How to display GUI message indicating which checkbutton(s) and radiobutton have been selected in tkinter in Python?

I am super new to Python and programming in general. I'm messing around in tkinter trying to make a silly and simple program so I can get more comfortable with it.
What I am doing with my program is asking for the user's name, age, if they remember certain events, and if they feel old or not. Like I said, it is supposed to be a light hearted program just to put my skills to the test.
Now I wonder, how to display GUI message indicating which checkbutton(s) and radiobutton have been selected in tkinter in Python?
Here is the code and a screenshot. I'll include a screenshot of my results but I can get the name and age to work like it should but can't get the message to appear correctly in the GUI with the checkboxes or radio button.
from tkinter import *
class MyFrame(Frame):
def __init__(self):
Frame.__init__(self)
self.master.geometry("600x400")
self.master.title("How to tell if you're old")
self.event = NONE
self.old = NONE
self.grid()
#user name and age
self.prompt = Label(self, text="What's your name?")
self.prompt.grid(row=0, column=0, pady=5)
self.input_name = Entry(self)
self.input_name.grid(row=0, column=1, pady=5)
self.prompt = Label(self, text="How old are you?")
self.prompt.grid(row=2, column=0, pady=5)
self.input_age = Entry(self)
self.input_age.grid(row=2, column=1, pady=10)
#user asks user if they remember certain events
self.prompt = Label(self, text="Which of these events do"
"you remember (may select more than one)?")
self.prompt.grid(row=3, columnspan=5, pady=5)
self.wheel_event = IntVar()
self.check_wheel_event = Checkbutton(self, text="Invention of the wheel",
variable=self.wheel_event, command=self.set_response_event)
self.check_wheel_event.grid(row=4, column=0, padx=5)
self.firstFlight_event = IntVar()
self.check_firstFlight_event = Checkbutton(self, text="First flight",
variable=self.firstFlight_event, command=self.set_response_event)
self.check_firstFlight_event.grid(row=4, column=1, padx=5)
self.Berlin_Wall_event = IntVar()
self.check_Berlin_Wall_event = Checkbutton(self, text="Berlin Wall",
variable=self.Berlin_Wall_event, command=self.set_response_event)
self.check_Berlin_Wall_event.grid(row=4, column=2, padx=5)
self.millennium_event = IntVar()
self.check_millennium_event = Checkbutton(self, text="Millennium",
variable=self.millennium_event, command=self.set_response_event)
self.check_millennium_event.grid(row=4, column=3, padx=5)
#user answers if they think they're old and if they want to know how
# old they'll be in 10, 15, or 20 years
self.prompt = Label(self, text="Do you consider yourself old?")
self.prompt.grid(row=5, column=0, pady=5)
self.feel_old = IntVar()
self.feel_old.set(4)
self.not_sure_old = Radiobutton(self, text="Not sure",
variable=self.feel_old, value="0")
self.not_sure_old.grid(row=6, column=0)
self.no_old = Radiobutton(self, text="No",
variable=self.feel_old, value="1")
self.no_old.grid(row=6, column=1)
self.yes_old = Radiobutton(self, text="Yes",
variable=self.feel_old, value="2")
self.yes_old.grid(row=6, column=2)
#submit button
self.button_submit = Button(self, text='Submit',
command=self.submit_click)
self.button_submit.grid
self.button_submit.grid(row=9, column=3, padx=10)
self.my_name = StringVar()
self.message = Label(self, textvariable=self.my_name)
self.message.grid(columnspan=2, pady=10)
self.my_age = StringVar()
self.message = Label(self, textvariable=self.my_age)
self.message.grid(columnspan=2, pady=10)
#response
def set_response_event(self):
#remembering events
if self.wheel_event.get() == 1:
self.event = "wheel"
elif self.firstFlight_event.get() == 1:
self.event = "firstFlight"
elif self.Berlin_Wall_event.get() == 1:
self.event = "Berlin_Wall"
elif self.millennium_event.get() == 1:
self.event = "millennium"
def set_response_old(self):
#feeling old
if self.not_sure_old.get() == "0":
self.old = "not_sure_old"
elif self.no_old.get() == "1":
self.old = "no_old"
elif self.yes_old.get() == "2":
self.old = "yes_old"
def submit_click(self):
output_message = 'Well ' + self.input_name.get() + ', to begin with you are ' + self.input_age.get() + '.\n'
output_message += 'You remember the ' + self.event +'.\n'
output_message += 'This means you are ' + self.old + '.'
self.my_name.set(output_message)
frame05 = MyFrame()
frame05.mainloop()
Here is what I get:
I realize I'm probably doing this the hard way but I feel like I'm really close. Thank you for your help!
First off, you are never calling set_response_old(self) that I can tell. Secondly you are trying to compare strings to integers, which doesn't get caught in your if statements. Try rewriting the last two functions like this:
def set_response_old(self):
#feeling old
if self.feel_old.get() == 0:
self.old = "not sure old"
elif self.feel_old.get() == 1:
self.old = "no old"
elif self.feel_old.get() == 2:
self.old = "yes old"
def submit_click(self):
self.set_response_old()
output_message = 'Well ' + self.input_name.get() + ', to begin with you are ' + self.input_age.get() + '.\n'
output_message += 'You remember the ' + self.event + '.\n'
output_message += 'This means you are ' + self.old + '.'
self.my_name.set(output_message)
When I run this it outputs
This means you are yes old.
Which I think is what you were going for.
#EDIT
As for getting the list of remembered events to show...You can add self.events_remembered = [] to your __init__ section to create a place to store the data (it's not required to be in the init section as the code below would make it anyways, but it's good practice!) and then change your set_response function as such:
def set_response_event(self):
#remembering events
self.events_remembered = [] # reset each time we are determining pressed events (so we don't just keep adding duplicates, and also remove any unchecked boxes)
if self.wheel_event.get() == 1:
self.events_remembered.append("wheel")
if self.firstFlight_event.get() == 1:
self.events_remembered.append("firstFlight")
if self.Berlin_Wall_event.get() == 1:
self.events_remembered.append("Berlin Wall")
if self.millennium_event.get() == 1:
self.events_remembered.append("millennium")
You are correct in thinking that the if will only catch the first one, but there is no rule against having a series of if statements like shown!
Finally you can update your submit_click function to search for this information and display the formatted list
def submit_click(self):
self.set_response_old()
self.set_response_event() # use the function we just updated
print(self.events_remembered)
output_message = 'Well ' + self.input_name.get() + ', to begin with you are ' + self.input_age.get() + '.\n'
output_message += 'You remember the ' + ", ".join(self.events_remembered) + '.\n'
output_message += 'This means you are ' + self.old + '.'
self.my_name.set(output_message)
Here we use ", ".join(iterable_list) to convert our python list to a nice comma separated list instead!
If this solved your question I would appreciate if you could accept the answer by clicking the check mark next to the post! If you really just like me you can click to upvote me too XD
To get all the checkbox values to the output, make self.event attribute a list
def __init__self():
...
...
self.event=[]
and when you call the set_response_event function, append those string values to that list.
def set_response_event(self):
#remembering events
if self.wheel_event.get() == 1:
self.event.append("wheel")
elif self.firstFlight_event.get() == 1:
self.event.append("firstFlight")
elif self.Berlin_Wall_event.get() == 1:
self.event.append("Berlin_Wall")
elif self.millennium_event.get() == 1:
self.event.append("millennium")
Finally print the list using .join function
'You remember the ' + ', '.join(self.event) + '\n'

Tkinter questionnaire based on get() method

I am trying to make my first GUI script based on the answers of 2 questions. I'll show an example of the non GUI script
while True:
ammount = input("What is your debt")
if ammount.isdigit() == True:
break
else:
print("Please try typing in a number")
while True:
month = input("In which month did the debt originate?")
if month not in ["January", "February"]:
print("Try again")
else:
break
The point of this script is that it is scalable with all the questions one may add, I want to understand it in the same way in Tkinter. I'll show what I've tried:
from tkinter import *
def click():
while True:
entered_text = text_entry.get()
if entered_text .isdigit() == False:
error = Label(window, text="Try again", bg = "black", fg="red", font="none 11").grid(row = 3, column = 2, sticky= W).pack()
else:
break
return True
window = Tk()
window.title("Tax calculator")
window.configure(background="black")
monto = Label(window, text="¿What is your debt?", bg="black", fg="white", font="none 12 bold")
monto.grid(row = 1, column = 0, sticky= W)
text_entry = Entry(window, width = 20, bg="white")
text_entry.grid(row = 2, column=2, sticky=W)
output = Button(window, text = "Enter", width = 6, command = click)
output.grid(row = 3, column = 0, sticky = W)
The thing is, I can't add a Label() method in the if/else of the click() method, because I would like to ask a new question once the condition is met. I can't also can't get True from click once the condition is met, because the input comes from Button() method. Thanks in advance
You don't actually need any loops here, a simple if statement would be enough to do the trick. Also, there is no need to recreate the label every time, you can just configure() its text. And, note that indexing starts from 0 - so, in your grid, actual first row (and column) needs to be numbered 0, not 1. Besides that, I suggest you get rid of import *, since you don't know what names that imports. It can replace names you imported earlier, and it makes it very difficult to see where names in your program are supposed to come from. You might want to read what PEP8 says about spaces around keyword arguments, as well:
import tkinter as tk
def click():
entered_text = text_entry.get()
if not entered_text.isdigit():
status_label.configure(text='Please try again')
text_entry.delete(0, tk.END)
else:
status_label.configure(text='Your tax is ' + entered_text)
text_entry.delete(0, tk.END)
root = tk.Tk()
root.title('Tax calculator')
root.configure(background='black')
monto = tk.Label(root, text='¿What is your debt?', bg='black', fg='white', font='none 12 bold')
monto.grid(row=0, column=0, padx=10, pady=(10,0))
text_entry = tk.Entry(root, width=20, bg='white')
text_entry.grid(row=1, column=0, pady=(10,0))
status_label = tk.Label(root, text='', bg='black', fg='red', font='none 11')
status_label.grid(row=2, column=0)
button = tk.Button(root, text='Enter', width=17, command=click)
button.grid(row=3, column=0, pady=(0,7))
root.mainloop()
I forgot to mention, if your application gets bigger, you might be better off using a class.

Python Tkinter error: "Label has no __call__method"

Im trying to create a Python tkinter login registeration but running into a small issue.
The error message is:
self.Label_Name = Label(top, text="What is your username: ")
AttributeError: Label instance has no __call__ method
Please can you proof read my code:
from Tkinter import *
class Register:
def __init__(self, parent):
top = self.top = Toplevel(parent)
# Variables to store the entries
self.VarEntUser = StringVar()
self.VarEntPass = StringVar()
self.VarEntRetype = StringVar()
self.Label_Name = Label(top, text="What is your username: ")
self.Label_Password = Label(top, text="Enter a password: ")
self.Label_Retype = Label(top, text="Retype Password: ")
# Entry fields for the user to enter there details
self.Ent_Name = Entry(top, textvariable=self.VarEntUser)
self.Ent_Password = Entry(top, textvariable=self.VarEntPass)
self.Ent_Retype = Entry(top, textvariable=self.VarEntRetype)
# Puts all the fields ^, into the window
self.Label_Name.grid(row=0, sticky=W)
self.Label_Password.grid(row=1, sticky=W)
self.Label_Retype.grid(row=2, sticky=W)
self.Ent_Password.grid(row=1, column=1)
self.Ent_Retype.grid(row=2, column=1)
self.Ent_Name.grid(row=0, column=2)
# Run the RegisterCheck function
# submit button which Checks the Entered details then writes the user and pass to a .txt file
self.MySubmitButton = Button(top, text='Submit', command=RegisterCheck)
self.MySubmitButton.pack()
self.U = raw_input(self.VarEntUser.get())
self.P = raw_input(self.VarEntPass.get())
self.R = raw_input(self.VarEntRetype.get())
class LogIn:
def __init__(self, parent):
top = self.top = Toplevel(parent)
self.a = StringVar()
self.b = StringVar()
self.Label_Log_User1 = Label(top, text='Username:')
self.Label_Log_Pass = Label(top, text='Password: ')
self.Ent_User_Log = Entry(top, textvariable=self.a)
self.Ent_Pass_Log = Entry(top, textvariable=self.b)
self.Label_Log_User1.grid(row=1)
self.Pass_Log.grid(row=2)
self.EntUserLog.grid(row=1, column=1)
self.EntPassLog.grid(row=2, column=1)
self.User = raw_input(self.EntUserLog.get())
self.Pass = raw_input(self.EntUserLog.get())
# runs the 'LoginCheck' function
self.LogInButton = Button(top, text="Log In", command=LogInCheck)
self.LogInButton.pack()
def LogInCheck(self):
# Checks if the fields are blanking displaying an error
if len(self.User) <= 0 and len(self.Pass) <= 0:
print "Please fill in all fields."
else:
pass
# Checks to see if the user and pass have been created
if self.User in 'username.txt' and self.Pass in 'password':
print 'You are now logged in!'
else:
print "Log in Failed"
def RegisterCheck(self):
# Checks if the fields are blank
if len(self.P) <= 0 and len(self.U) <= 0:
print "Please fill out all fields."
else:
pass
# Check is the password and the retype match
if self.P == self.R:
pass
else:
print "Passwords do not match"
# After registering write the user and pass to a .txt file
with open('username.txt', 'a') as fout:
fout.write(self.U + '\n')
with open('password.txt', 'a') as fout:
fout.write(self.P + '\n')
# Depending on what the user chooses, either log in or register than opens the specific window
def launch_Register():
inputDialog = Register(root)
root.wait_window(inputDialog.top)
def launch_LogIn():
inputdialog2 = LogIn(root)
root.wait_window(inputdialog2.top)
root = Tk()
label = Label(root, text='Choose an option')
label.pack()
loginB = Button(root, text='Log In', command=launch_LogIn)
loginB.pack()
registerB = Button(root, text='Register', command=launch_Register)
registerB.pack()
root.mainloop()
The problem is that in this line
Label = Label(root, text='Choose an option')
you define a Label called Label, thus shadowing the Label constructor. Then, then you create the several labels in your Register and Login classes (triggered by those two buttons), the name Label is no longer bound to the constructor, but to that specific label.
Change the name of the label, then it should work. Also, I would advise you to use lower-case names for variables and methods. This alone might help prevent many such errors.
root = Tk()
label = Label(root, text='Choose an option')
label.pack()
loginB = Button(root, text='Log In', command=launch_LogIn)
loginB.pack()
registerB = Button(root, text='Register', command=launch_Register)
registerB.pack()
root.mainloop()
Note that there are a few many more problems with your code:
StringVar a and b should probably be self.a and self.b
You are trying to use raw_input to get the user input in the Entry widgets; this is wrong! Instead, just read the value of the variables to get the values, e.g. instead of self.User, use self.a.get()
do not mix grid and pack layout
if self.User in 'username.txt' will not check whether that name is in that file
loginCheck and registerCheck should be methods of the respective class
Once I'm at it, here's (part of) my version of your code, to help you getting started:
class Register:
def __init__(self, parent):
top = self.top = Toplevel(parent)
self.var_user = StringVar()
self.var_pass = StringVar()
self.var_retype = StringVar()
Label(top, text="What is your username: ").grid(row=0, sticky=W)
Label(top, text="Enter a password: ").grid(row=1, sticky=W)
Label(top, text="Retype Password: ").grid(row=2, sticky=W)
Entry(top, textvariable=self.var_user).grid(row=0, column=1)
Entry(top, textvariable=self.var_pass).grid(row=1, column=1)
Entry(top, textvariable=self.var_retype).grid(row=2, column=1)
Button(top, text='Submit', command=self.registerCheck).grid(row=3)
def registerCheck(self):
u, p, r = self.var_user.get(), self.var_pass.get(), self.var_retype.get()
if p and u:
if p == r:
logins[u] = p
else:
print "Passwords do not match"
else:
print "Please fill out all fields."
class LogIn:
# analogeous to Register; try to figure this out xourself
def launch_Register():
inputDialog = Register(root)
root.wait_window(inputDialog.top)
def launch_LogIn():
inputDialog = LogIn(root)
root.wait_window(inputDialog.top)
logins = {}
root = Tk()
Label(root, text='Choose an option').pack()
Button(root, text='Log In', command=launch_LogIn).pack()
Button(root, text='Register', command=launch_Register).pack()
root.mainloop()
Note that I changed the login "database" from files to a dictionary to keep things simple and to focus on the Tkinter problems. Of course, neither a simple dictionary nor a plain-text file is an appropriate way to store login information.
Also, I put the creation and the layout of the GUI widgets on one line. In this case this is possible since we do not need a reference to those widgets, but beware never to do e.g. self.label = Label(...).grid(...), as this will bind self.label to the result of grid, and not to the actual Label.
Finally, this will still print all the messages to the standard output. Instead, you should add another Label for that, or open a message dialogue, but this is left as an excercise to the reader...

Categories