Inicio de sesión en la GUI de Python Tkinter
He estado programando durante aproximadamente 4 a 5 meses e hice un script de inicio de sesión con tkinter en python. Traté de usar clases y definiciones de funciones lo mejor que pude. Para conocerlos mejor.
Quería preguntarles a todos, ¿cómo se ve este código y hay algo que debería o no debería hacer la próxima vez que codifique?
GRACIAS DE ANTICIPADO POR TODAS SUS SUGERENCIAS
from tkinter import *
import tkinter.font as font
import time
global data
data = {}
class Visual:
def __init__(self,old_root):
old_root.destroy()
self.root = Tk()
self.win_size = self.root.geometry("800x500")
self.color = self.root.configure(bg="black")
self.font = font.Font(size= 30)
self.home_screen()
# print data to check and see what is in data
print(data)
def home_screen(self):
# just title on the home screen
title = Label(self.root, text= "WELCOME USER , PLEASE LOGIN BELOW ",padx= 200,anchor= "center" ,bg="grey")
title.place(relx= 0.5, rely= 0.0 , anchor= "n")
# the login fields and the enter button
self.entery()
def entery(self):
# a text that says "username" next to the input field
user_text = Label(self.root, text= "USERNAME :", bg="grey")
# the username input field
username = Entry(self.root, width= 50)
# a text that says "password" next to the input field
passw_text = Label(self.root, text= "PASSWORD :", bg= "grey")
# the password input field
password = Entry(self.root, width= 50)
# puts the text and the user input fields on the screen
user_text.place(rely= 0.1, anchor= "nw")
username.place(relx= 0.1, rely= 0.1, anchor= "nw")
# puts the text and the user input fields on the screen
passw_text.place(rely= 0.2,anchor= "nw")
password.place(relx= 0.1, rely= 0.2, anchor= "nw")
# button that is clicked when finished with inputting your login information
submit = Button(self.root, text= "ENTER", padx= 80, pady= 10, command=lambda :Login(username_clear=username,
password_clear= password,
root= self.root,
user_input= username.get(),
passw_input= password.get()))
submit.place(relx= 0.6, rely= 0.2, anchor= "sw")
self.root.mainloop()
class Login:
def __init__(self, username_clear , password_clear , root, user_input, passw_input):
# clears the input fields
username_clear.delete(0,END)
password_clear.delete(0,END)
self.root = root
self.user_input = user_input
self.passw_input = passw_input
self.login_check()
def login_check(self):
key, value = self.user_input , self.passw_input
# Checks to see if username and password exists
if key in data and value == data[key]:
# Welcomes the user back
welcome = Label(self.root, text= f"WELCOME BACK \n{self.user_input.upper()}", padx= 200, pady= 50)
welcome.place(relx= 0.2, rely= 0.5, anchor= "nw")
# Checks to see if the user put in the wrong username or password
elif key not in data or value != data[key]:
wrong= Label(self.root, text="Wrong Username or Password", padx =200)
wrong.place(relx= 0.1, rely= 0.5,anchor= "nw")
# Creates a input field for the user to see if he/she is a new user or not
question = Entry(self.root, width= 20)
question.place(relx= 0.25, rely=0.6, anchor="nw")
question_text = Label(self.root, text= "Are You A New User? Yes / No : ")
question_text.place(relx= 0.01, rely= 0.6, anchor= "nw")
# Make a button for the user to press when finished with answering the question above
enter_answ = Button(self.root, text= "ENTER", width= 30, command= lambda : self.answer_check(answer=question.get()))
enter_answ.place(relx= 0.6, rely= 0.6)
self.root.mainloop()
def answer_check(self, answer):
# If the user types the answer yes. It destroys this window and makes a new one create a new user
if answer == "yes":
New_user(root=self.root)
# If user answers with no , then it starts again and asks user to login
if answer == "no" :
Visual(old_root=self.root)
class New_user:
def __init__(self, root):
# Destroyes the old window and creates a new one after it
root.destroy()
self.data = data
# Creates a new window to create a new user
self.new_root = Tk()
self.win_size = self.new_root.geometry("800x500")
self.color = self.new_root.configure(bg="black")
self.font = font.Font(size=30)
self.home_screen()
def home_screen(self):
title = Label(self.new_root, text="CREATE NEW USER LOGIN ", padx=200, anchor="center", bg="grey")
title.place(relx=0.5, rely=0.0, anchor="n")
self.regestration()
def regestration(self):
# The input fields for the new login information for the new user account
user_text = Label(self.new_root, text="USERNAME :", bg="grey")
username = Entry(self.new_root, width=50)
passw_text = Label(self.new_root, text="PASSWORD :", bg="grey")
password = Entry(self.new_root, width=50)
user_text.place(rely=0.1, anchor="nw")
username.place(relx=0.1, rely=0.1, anchor="nw")
passw_text.place(rely=0.2, anchor="nw")
password.place(relx=0.1, rely=0.2, anchor="nw")
# Create a button to verify if the user information already exists
submit = Button(self.new_root, text="CREATE USER", padx=80, pady=10, command=lambda :self.save_new_user(username= username,
password= password))
submit.place(relx=0.6, rely=0.2, anchor="sw")
def save_new_user(self, username, password):
# if user information already exists , it waits 2seconds then destroys the current window and makes a new window for the user to create a new account
if username.get() in data:
in_use = Label(self.new_root, text= "USERNAME ALEARDY EXISTS", padx= 200)
in_use.place(relx= 0.0, rely= 0.7, anchor= "sw")
time.sleep(2)
New_user(root=self.new_root)
# If the user information doesn't exists yet , it puts it into the a dictionary called "data"
data[username.get()] = password.get()
# Assigns a button to verify your succesfull login and also destroying the button at the sametime and creating a diffrent one .
login_retry = Button(self.new_root ,text="LOGIN", width= 80, command=lambda :self.succes(button=login_retry))
login_retry.place(relx= 0.15, rely= 0.8)
def succes(self,button):
# Destroy the old button
button.destroy()
# Tells the user that he/she succesfully logged in .
succes_login = Label(self.new_root, text="YOU HAVE SUCCESFULLY CREATED A NEW USER , CLICK BELOW TO LOGIN IN ",
padx=200)
succes_login.place(relx=0.0, rely=0.5, anchor="sw")
# Creates a button to verify your new user account
Button(self.new_root, text="Click HERE TO LOGIN", width= 100, command=lambda :self.retry_login()).place(relx= 0.05, rely= 0.6)
self.new_root.mainloop()
def retry_login(self):
# Goes to the beginning of the program where you test your account login
Visual(old_root=self.new_root)
root = Tk()
main = Visual(root)
Respuestas
Algunos comentarios habituales de PEP8:
username_clear.delete(0,END) -> username_clear.delete(0, END)
in_use.place(relx= 0.0, rely= 0.7, anchor= "sw") -> in_use.place(relx=0.0, rely=0.7, anchor="sw")
New_userdebería haber sido NewUserpara un nombre de clase o new_useren otros casos
Elija nombres significativos y evite errores tipográficos
Evite errores tipográficos como: regestrationy Visualpodría haber sidoMainWindow
Registro de nuevo usuario
La opción de registro aparece solo después de que se haya enviado un inicio de sesión incorrecto, debería haber estado en la primera visualización de la pantalla
Verificar inconsistencias
Pide Sí / No, pero compruebe:
if answer == "yes":
New_user(root=self.root)
# If user answers with no , then it starts again and asks user to login
if answer == "no" :
Visual(old_root=self.root)
Usando .lowero .casefoldhace una mejor comparación
if answer.lower() == "yes":
lo mismo para no
La clase de inicio de sesión podría haber sido métodos
La clase de inicio de sesión podría haber sido más métodos en Visual. Entiendo que agrupó funcionalidades en temas como Inicio de sesión y New_user, pero no usa el constructor como reemplazo de un método:
def __init__(self, username_clear , password_clear , root, user_input, passw_input):
# clears the input fields
username_clear.delete(0,END)
password_clear.delete(0,END)
self.root = root
self.user_input = user_input
self.passw_input = passw_input
self.login_check()
MVC
También puede agrupar todas las vistas en una clase y toda la lógica en una clase. Las vistas toman la lógica como parámetro y llaman a los métodos relevantes según sea necesario. Esto hace que, entre otros, sea más fácil de encontrar y probar.
Estoy de acuerdo con Abdur que sea sencillo con una clase. Otras cosas que podrían mejorarse son:
- Agregue una base de datos, puede usar pickle o shelve para almacenar nombres de usuario y contraseñas. comienzo básico a los estantes
2) Agregue un botón para nuevos usuarios de inmediato. 3) su uso de relx y confía tiene algunos efectos secundarios superpuestos que podría ser mejor si usa xey con coordenadas reales. 4) Las entradas de su contraseña puede ocultar la palabra con mostrar:
password= Entry(self.root,show='*',width=60)
5) Para agregar argumentos a un comando de botón, puede usar parcial de functools
from functools import partial
el lado del botón:
submit= Button(self.root,text='Enter',command=partial(your_function,args,arg,arg)
- por último, creé un nuevo usuario y cuando inicié sesión, escribí intencionalmente una contraseña diferente, arrojó un error. Necesita alguna forma de verificar y decirle al usuario que las cosas no coinciden. Un cuadro de diálogo o cuadro de mensaje simple funcionaría. la mejor de las suertes, Joe