Logowanie do interfejsu GUI Python Tkinter

Sep 19 2020

Programuję od około 4 do 5 miesięcy i wykonałem skrypt logowania w tkinter w Pythonie. Starałem się jak najlepiej używać klas i definicji funkcji. Aby lepiej ich poznać.

Chciałem was wszystkich zapytać, jak wygląda ten kod i czy jest coś, co powinienem, a czego nie powinienem robić następnym razem?

DZIĘKI ZAAWANSOWANE ZA WSZYSTKIE TWOJE PROPOZYCJE

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)

Odpowiedzi

2 Abdur-RahmaanJanhangeer Sep 21 2020 at 15:55

Niektóre typowe komentarze 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_userpowinno być albo NewUserdla nazwy klasy, albo new_userw innych przypadkach

Wybierz znaczące nazwy i unikaj literówek

Unikaj literówek typu: regestrationi Visualmogło byćMainWindow

Rejestracja nowego użytkownika

Opcja rejestracji pojawia się dopiero po podaniu błędnego loginu, powinna być na pierwszym ekranie

Sprawdź niespójności

Pytasz o Tak / Nie, ale sprawdź:

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)

Używanie .lowerlub .casefoldlepsze porównanie

if answer.lower() == "yes":

to samo dla nie

Klasa Login mogła być metodami

Klasa Login mogłaby mieć więcej metod w Visual. Rozumiem, że zgrupowałeś funkcjonalności w tematach takich jak Login i New_user, ale nie używasz konstruktora jako zamiennika metody:

    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

Możesz także zgrupować wszystkie widoki w jednej klasie i całą logikę w jednej klasie. Widoki przyjmują logikę jako parametr i w razie potrzeby wywołują odpowiednie metody. Dzięki temu łatwiej jest znaleźć i przetestować.

2 just_joe Sep 22 2020 at 09:11

Zgadzam się z Abdurem, zachowaj prostotę z jedną klasą. Inne rzeczy, które można poprawić, to:

  1. Dodaj bazę danych, możesz użyć piklowania lub półki do przechowywania nazw użytkowników i haseł. podstawowy start do półek

2) Od razu dodaj przycisk dla nowych użytkowników. 3) użycie relx i rely ma pewne nakładające się efekty uboczne, lepiej byłoby, gdybyś użył x i y z rzeczywistymi współrzędnymi. 4) Twoje wpisy hasła możesz ukryć słowo za pomocą show:

password= Entry(self.root,show='*',width=60)

5) Aby dodać argumenty do polecenia przycisku, możesz użyć częściowych z functools

from functools import partial

strona guzika:

submit= Button(self.root,text='Enter',command=partial(your_function,args,arg,arg)
  1. na koniec utworzyłem nowego użytkownika i kiedy się logowałem celowo wpisałem inne hasło, wyrzuciło to błąd. Potrzebujesz sposobu na sprawdzenie i poinformowanie użytkownika, że ​​coś się nie zgadza. Proste okno dialogowe lub skrzynka wiadomości działałyby. powodzenia, Joe