Issue
When I am trying to add username
and password
in the sign in page, it gives me an error:
TypeError: argument should be integer or None, not 'str'
The issue is occurring in the sign-in page. The whole code is listed below:
import tkinter
from tkinter import messagebox
from tkinter import StringVar
class panel:
def ask(self):
ask = tkinter.Tk()
ask.title("Input")
ask.geometry("300x100")
def y():
ask.destroy()
self.login()
def n():
ask.destroy()
self.signup()
stat = tkinter.Label(ask , text = "Are You An Existing User?")
stat.grid(row = 0 , column = 0)
yes = tkinter.Button(ask, text = "Yes" , bg = "Blue" , fg = "Black" , command = y, bd = 5 )
yes.grid(row = 1 , column = 1)
no = tkinter.Button(ask, text = "No" , bg = "Blue", fg = "Black" , command = n, bd = 5)
no.grid(row = 1 , column = 2)
ask.mainloop()
def signup(self):
window = tkinter.Tk()
window.title("Registration Form")
window.geometry("300x300")
var = StringVar()
def callback():
file = open("information.txt", "a")
file.write("\r")
file.write("Data: ")
file.write(firstname1.get())
file.write(" ")
file.write(lastname1.get())
file.write("\n")
file.write(firstname1.get())
file.write("\n")
file.write(lastname1.get())
file.write("\n")
file.write(email1.get())
file.write("\n")
file.write(password1.get())
file.write("\n")
file.write(var.get())
file.write("\r")
file.close()
messagebox.showinfo("Signup", "You have Successfully Signed Up")
self.login()
firstname = tkinter.Label(window, text= "First Name", bg = "Black",fg = "White")
firstname.grid(row= 0, column= 0)
firstname1= tkinter.Entry(window,bd= 5)
firstname1.grid(row= 0 , column = 1)
lastname = tkinter.Label(window, text = "Last Name", bg = "Black", fg = "White")
lastname.grid(row = 1, column = 0)
lastname1= tkinter.Entry(window, bd = 5)
lastname1.grid(row = 1, column = 1)
email = tkinter.Label(window, text = "Email", bg = "Black", fg = "White")
email.grid(row = 2, column = 0)
email1 = tkinter.Entry(window, bd = 5)
email1.grid(row = 2 , column = 1)
password = tkinter.Label(window, text = "Password" , bg = "Black", fg = "White")
password.grid(row = 3 , column = 0)
password1= tkinter.Entry(window, bd = 5)
password1.grid(row = 3 , column = 1)
gender= tkinter.Label(window, text = "Gender", bg = "Black", fg = "White")
gender.grid(row = 4 , column = 0)
male = tkinter.Radiobutton(window,text= "Male" , value = "Male", variable = var )
male.grid(row = 4 , column = 1 , sticky = "nsew")
female = tkinter.Radiobutton(window,text= "Female" , value= "Female" , variable = var)
female.grid(row = 4, column = 2 , sticky = "nsew")
button = tkinter.Button(window, text = "Submit" ,command = callback , bg = "Blue", fg = "White" , height = 2, width = 14)
button.grid(row = 5 , column = 1 , rowspan= 315)
window.mainloop()
def login(self):
signin = tkinter.Tk()
signin.title("Sign In")
signin.geometry("300x300")
def callback():
file = open("information.txt" , "r")
e = file.read(x1.get())
print(e)
p = file.read(y1.get())
print(p)
if e in file and p in file:
messagebox.showinfo("SignIn Notification", "You are Successfully Signed In")
else:
messagebox.showerror("Error", "Email or Password is Incorrect")
file.close()
x = tkinter.Label(signin, text = "Email", bg = "Black", fg = "White" )
x.grid(row = 0 , column = 0)
x1 = StringVar(tkinter.Entry(signin, bd = 5).grid(row = 0 , column = 1))
y = tkinter.Label(signin, text = "Password", bg = "Black", fg = "White")
y.grid(row = 1 , column = 0)
y1 = StringVar(tkinter.Entry(signin, bd = 5).grid(row = 1 , column = 1))
login = tkinter.Button(signin, text = "Sign In" , bd = 5, bg = "Blue" , fg = "Black", height = 2 , width = 10, command = callback )
login.grid(row = 2 , column = 1, rowspan = 2)
signin.mainloop()
def main():
p = panel()
p.ask()
main()
Solution
The main reason for your error is that
get()
returns a string andread()
either takes no arguments or an integer. The integer just tells how many bytes to read.The way you have written your callback even if it worked would actually work if any user and any password matched not just for that specific user. Personally I would store this information in a dictionary and then check each user in that dictionary for the email and password.
I would place all the entry values and the StringVar into a list dynamically so we can use it when creating a new user.
You are currently using multiple instances of
Tk()
and should only be using one. In order to do the same thing you are doing now we can either use a central frame we can update per window our useToplevel()
to create new windows.You can actually build all this functionality into a single class if you want. Right now you have a lot of different things going on that may not need to be. For example your functions
y
andn
can be deleted.You may want to look into PEP8 standards. Your spacing is all over the place.
After reworking your code I reduced it from 128 lines to 94. I could probably reduce it further but I didn't want to make anything too confusing.
Here is a reworked example of your code let me know if you have any questions:
import tkinter as tk
from tkinter import messagebox
import json
class Main(tk.Tk):
def __init__(self):
super().__init__()
self.title("Input")
self.geometry("300x100")
self.frame = tk.Frame(self)
self.lbl_list = ['First Name', 'Last Name', 'Email', 'Password', 'Gender']
self.entry_list = []
self.build_pain_1()
def clear_frame(self):
self.frame.destroy()
self.frame = tk.Frame(self)
self.frame.grid(row=0, column=0, sticky='nsew')
def build_pain_1(self):
self.clear_frame()
tk.Label(self.frame, text="Are You An Existing User?").grid(row=0, column=0)
tk.Button(self.frame, text="Yes", bg="Blue", fg="Black", command=self.login, bd=5).grid(row=1, column=1)
tk.Button(self.frame, text="No", bg="Blue", fg="Black", command=self.signup, bd=5).grid(row=1, column=2)
def signup_callback(self):
with open("information.txt", "r") as f:
file_dict = json.load(f)
new_dict = {}
for ndex, value in enumerate(self.lbl_list):
print(self.entry_list[ndex].get())
new_dict[value] = self.entry_list[ndex].get()
file_dict["user {}".format(len(file_dict)+1)] = new_dict
with open("information.txt", "w") as file:
json.dump(file_dict, file, indent=4)
self.login()
def signup(self):
self.clear_frame()
self.title("Registration Form")
self.geometry("300x300")
for ndex, txt in enumerate(self.lbl_list):
if ndex+1 < len(self.lbl_list):
tk.Label(self.frame, text=txt, bg="Black", fg="White").grid(row=ndex, column=0)
self.entry_list.append(tk.Entry(self.frame, bd=5))
self.entry_list[-1].grid(row=ndex, column=1)
if ndex+1 == len(self.lbl_list):
tk.Label(self.frame, text="Gender", bg="Black", fg="White").grid(row=ndex, column=0)
self.entry_list.append(tk.StringVar(self))
tk.Radiobutton(self.frame, text="Male", value="Male", variable=self.entry_list[-1],
tristatevalue="x").grid(row=4, column=1, sticky="nsew")
tk.Radiobutton(self.frame, text="Female", value="Female", variable=self.entry_list[-1],
tristatevalue="x").grid(row=4, column=2, sticky="nsew")
tk.Button(self.frame, text="Submit", bg="Blue", fg="White", height=2,
command=self.signup_callback).grid(row=5, column=1)
def login_callback(self):
e = self.email.get()
p = self.passw.get()
valid_login = False
with open("information.txt", "r") as f:
file_dict = json.load(f)
for key, value in file_dict.items():
if file_dict[key]["Email"] == e and file_dict[key]["Password"] == p:
messagebox.showinfo("SignIn Notification", "You are Successfully Signed In")
valid_login = True
if not valid_login:
messagebox.showerror("Error", "Email or Password is Incorrect")
def login(self):
self.clear_frame()
self.title("Sign In")
self.geometry("300x300")
tk.Label(self.frame, text="Email", bg="Black", fg="White").grid(row=0, column=0)
self.email = tk.Entry(self.frame, bd=5)
self.email.grid(row=0, column=1)
tk.Label(self.frame, text="Password", bg="Black", fg="White").grid(row=1, column=0)
self.passw = tk.Entry(self.frame, bd=5)
self.passw.grid(row=1, column=1)
tk.Button(self.frame, text="Sign In", bd=5, bg="Blue", fg="Black", height=2, width=10,
command=self.login_callback).grid(row=2, column=1, rowspan=2)
if __name__ == '__main__':
Main().mainloop()
Answered By - Mike - SMT
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.