Accesso alla GUI di Python Tkinter
Sto programmando da circa 4 a 5 mesi e ho creato uno script di accesso con tkinter in python. Ho cercato di utilizzare le classi e le definizioni di funzione nel miglior modo possibile. Per conoscerli meglio.
Volevo chiedere a tutti voi, come appare questo codice e c'è qualcosa che dovrei o non dovrei fare la prossima volta che codifico?
GRAZIE IN AVANZATO PER TUTTI I TUOI SUGGERIMENTI
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)
Risposte
Alcuni soliti commenti di 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_useravrebbe dovuto essere NewUserper un nome di classe o new_userin altri casi
Scegli nomi significativi ed evita errori di battitura
Evita errori di battitura come: regestratione Visualavrebbe potuto essereMainWindow
Nuova registrazione utente
L'opzione di registrazione viene visualizzata solo dopo aver effettuato un accesso errato, avrebbe dovuto essere sulla prima visualizzazione dello schermo
Controlla le incongruenze
Chiedete Sì / No ma controllate:
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)
Utilizzando .lowero .casefoldfa un confronto migliore
if answer.lower() == "yes":
lo stesso per no
La classe Login avrebbe potuto essere metodi
La classe Login avrebbe potuto essere più metodi in Visual. Capisco che hai raggruppato le funzionalità in argomenti come Login e New_user ma non usi il costruttore come sostituto di un metodo:
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
Puoi anche raggruppare tutte le viste in una classe e tutta la logica in una classe. Le viste prendono la logica come parametro e chiamano i metodi rilevanti secondo necessità. Questo rende, tra l'altro, più facile da trovare e testare.
Sono d'accordo con Abdur mantenerlo semplice con una classe. Altre cose che potrebbero essere migliorate sono:
- Aggiungi un database, puoi usare pickle o shelve per memorizzare nomi utente e password. inizio di base agli scaffali
2) Aggiungi subito un pulsante per i nuovi utenti. 3) il tuo uso di relx e affidamento ha alcuni effetti collaterali che si sovrappongono potresti essere meglio usare xey con coordinate reali. 4) Le voci della tua password puoi nascondere la parola con spettacolo:
password= Entry(self.root,show='*',width=60)
5) Per aggiungere argomenti a un comando pulsante puoi usare partial from functools
from functools import partial
lato pulsante:
submit= Button(self.root,text='Enter',command=partial(your_function,args,arg,arg)
- infine ho creato un nuovo utente e quando mi sono loggato ho digitato di proposito una password diversa, si è verificato un errore. Hai bisogno di un modo per controllare e dire all'utente che le cose non corrispondono. Un semplice dialogo o una casella di messaggio funzionerebbe. buona fortuna, Joe