0

This project is an Inventory Management system. I am still a beginner My code has a lot of issues, which I know. Right now I am struggling with using two different classes together. (I also think I don't need to use classes if I can't organizing my code which is why I opted for it in the first place)

from tkinter import *
import customtkinter as ctk
from CTkMessagebox import CTkMessagebox
import mysql.connector


class Inventory():
    conn = mysql.connector.connect(host='localhost', user='root', password='1810', database='inventory')
    csr = conn.cursor()
    Logged_in = False
    #Initialization of onject variables
    def __init__(self):
        #Inheritance
        super().__init__()
        
        self.login = ctk.CTk()
        self.login.title('Inventory Management')
        self.login.geometry("800x600+10+10")
        self.login.resizable(False,False)

        #Username input
        self.usrname_label = ctk.CTkLabel(self.login, text="Username--", font=("Helvetica", 13))
        self.usrname_label.place(x=145,y=110)
        self.usrnm_input = ctk.CTkEntry(self.login, bg_color='white', fg_color='#AFE8DF', border_width=5)
        self.usrnm_input.place(x=230, y=110)

        #password input
        self.pswd_label = ctk.CTkLabel(self.login, text="Password--", font=("Helvetica", 13))
        self.pswd_label.place(x=145,y=150)
        self.pswd_input = ctk.CTkEntry(self.login, bg_color='white', fg_color='#AFE8DF', border_width=5, show='*')
        self.pswd_input.place(x=230, y=150)

        #buttons
        self.login_btn = ctk.CTkButton(self.login, text="LOGIN", bg_color='white', fg_color='blue', command= self.check )
        self.login_btn.place(x=230, y=200)
        self.welcm= Label(self.login, text="Welcome to Inventory Management", fg='#E6A405', font=("Helvetica", 25))
        self.welcm.place(x=140, y=40)
        self.fgt_btn = ctk.CTkButton(self.login, text="Forgot Password",bg_color='#00A7E5', fg_color='#00081F', command = self.forgot_passward )
        self.fgt_btn.place(x=280, y=400)
        self.sin_up = ctk.CTkButton(self.login, text="New User?", bg_color='#00A7E5', fg_color='#00081F', command = self.sign_up )
        self.sin_up.place(x=430, y=400)

        #Looping the login window
        self.login.mainloop()

        


    #to check login details
    def check(self):
        username = self.usrnm_input.get().strip()
        pswd = self.pswd_input.get()
        if username == "":
            no_user = CTkMessagebox(
                title="Credentials Error !",
                message="Pleaase enter login details",
                option_1="Retry",
                icon = "cancel"
            )
        else:
            Inventory.csr.execute("SELECT * FROM Users WHERE Username = '{}'".format(username))
            user = Inventory.csr.fetchone()
        if user:
            if pswd in user:
                msg = CTkMessagebox(title = "Login", message="Login Successful !", option_1 = "Ok")
                if msg.get() == "Ok":
                    Inventory.Logged_in = True
                    self.login.withdraw()
                    self.usrnm_input.delete(0, END)
                    self.pswd_input.delete(0, END)
                    self.start_menu()
            else:
                inc_pswd = CTkMessagebox(
                title="Credentials Error !",
                message="Wrong password",
                option_1="Retry",
                icon = "cancel"
            )
        else:
            self.inc_usr()

#For Forgot Password Page
    def forgot_passward(self):
        self.fgt_window = ctk.CTk()
        self.fgt_window.geometry('800x600')
        self.fgt_window.title('Forgot Password')
        self.funam_lbl = ctk.CTkLabel(self.fgt_window, text="Username--", font=("Helvetica", 13))
        self.funam_lbl.place(x=165,y=110)
        self.funam_txt = ctk.CTkEntry(self.fgt_window, border_width=5, fg_color='#AFE8DF')
        self.funam_txt.place(x=250, y=110)
        self.fnam_lbl = ctk.CTkLabel(self.fgt_window, text="Name--", font=("Helvetica", 13))
        self.fnam_lbl.place(x=165,y=75)
        self.fnam_txt = ctk.CTkEntry(self.fgt_window, border_width=5, fg_color='#AFE8DF')
        self.fnam_txt.place(x=250, y=75)
        self.fsk_lbl = ctk.CTkLabel(self.fgt_window, text="Security Key--", font=("Helvetica", 13))
        self.fsk_lbl.place(x=165,y=145)
        self.fsk_txt = ctk.CTkEntry(self.fgt_window, border_width=5, fg_color='#AFE8DF')
        self.fsk_txt.place(x=250, y=145)
        self.fnxt_btn = ctk.CTkButton(self.fgt_window, text="Next",bg_color='#00A7E5', fg_color='#00081F', command = self.forgot_pswd_check)
        self.fnxt_btn.place(x=252, y=200)
        self.fgt_window.mainloop()
        
#For checking details for forgot password window
    def forgot_pswd_check(self):
        username = self.funam_txt.get().strip()
        s_key = int(self.fsk_txt.get().strip())
        name = self.fnam_txt.get().strip()
        if username == "" or s_key == "" or name == "":
            no_user = CTkMessagebox(
                title="Credentials Error !",
                message="Pleaase enter login details",
                option_1="Retry",
                icon = "cancel"
            )
            user = False
        else:
            Inventory.csr.execute("SELECT * FROM Users WHERE Username = '{}'".format(username))
            user = Inventory.csr.fetchone()
            print("\n\n\n"+str(user)+"\n\n\n")
        if user:
            if (name == user[1]) and (s_key == user[3]):
                self.frgt_pswd_user = user
                self.cre_vrf()
            elif s_key not in user:
                self.inc_sk()
            else:
                msg = CTkMessagebox(
                    title="Inncorrect Credentials!", message="Incorrect Name",
                            option_1="Ok"
                )
        else:
            self.inc_usr()

    #Verification of credentials
    #After checking from database returns the message after 
    def cre_vrf(self):
        cr_vrf = CTkMessagebox(title="Change Password", message="Credentials Verified !", option_1="Cont...")
        if cr_vrf.get()=="Cont...":
            self.fgt_window.destroy()
            self.Paswd_cng()
    #cont... button takes to change password page
        
        
    #To change password
    def Paswd_cng(self):
        self.pswd_cng = ctk.CTk()
        self.pswd_cng.geometry('600x600')
        self.pswd_cng.title('Change Password')
        self.fpw_lbl = ctk.CTkLabel(self.pswd_cng, text="Password--", font=("Helvetica", 13))
        self.fpw_lbl.place(x=125,y=145)
        self.new_pswd_entry = ctk.CTkEntry(self.pswd_cng, border_width=5, fg_color='#AFE8DF')
        self.new_pswd_entry.place(x=250, y=145)
        self.retype_pswd = ctk.CTkLabel(self.pswd_cng, text="Retype Password--", font=("Helvetica", 13))
        self.retype_pswd.place(x=125,y=180)
        self.retype_pswd_entry = ctk.CTkEntry(self.pswd_cng, border_width=5, fg_color='#AFE8DF')
        self.retype_pswd_entry.place(x=250, y=180)
        self.fpw_btn = ctk.CTkButton(self.pswd_cng, text="Cont...",bg_color='#00A7E5', fg_color='#00081F', command=self.cng_psd_prcs)
        self.fpw_btn.place(x=250, y=230)
        self.pswd_cng.mainloop()
        

    def cng_psd_prcs(self):
        psd = self.new_pswd_entry.get()
        if psd == self.retype_pswd_entry.get():
            Inventory.csr.execute("UPDATE Users SET pswd = '{}' WHERE Username = '{}'".format(psd, self.frgt_pswd_user[0]))
            Inventory.conn.commit()
            self.Paswd_ssfl()
        else:
            msg = CTkMessagebox(title = "Retype passwords", cancel = "Passwords Do not match", option_1="Ok")

    #To notify password change successful
    def Paswd_ssfl(self):
        paswd_sf = CTkMessagebox(title="Password Change!", message="Password Change successful, Please",option_1="Login")
        if paswd_sf.get() == "Login":
            self.pswd_cng.destroy()


    #For Sign Up page 
    def sign_up(self):
        self.sin_up = ctk.CTk()
        self.sin_up.geometry('600x600')
        self.sin_up.title('Sign Up')
        self.sunam_lbl = ctk.CTkLabel(self.sin_up, text="Username--", font=("Helvetica", 13))
        self.sunam_lbl.place(x=125,y=110)
        self.sunam_txt = ctk.CTkEntry(self.sin_up, border_width=5, fg_color='#AFE8DF')
        self.sunam_txt.place(x=250, y=110)
        self.snam_lbl = ctk.CTkLabel(self.sin_up, text="Name--", font=("Helvetica", 13))
        self.snam_lbl.place(x=125,y=75)
        self.snam_txt = ctk.CTkEntry(self.sin_up, border_width=5, fg_color='#AFE8DF')
        self.snam_txt.place(x=250, y=75)
        self.spw_lbl = ctk.CTkLabel(self.sin_up, text="Password--", font=("Helvetica", 13))
        self.spw_lbl.place(x=125,y=145)
        self.spw_txt = ctk.CTkEntry(self.sin_up, border_width=5, fg_color='#AFE8DF')
        self.spw_txt.place(x=250, y=145)
        self.srpw_lbl = ctk.CTkLabel(self.sin_up, text="Retype Password--", font=("Helvetica", 13))
        self.srpw_lbl.place(x=125,y=180)
        self.srpw_txt = ctk.CTkEntry(self.sin_up, border_width=5, fg_color='#AFE8DF')
        self.srpw_txt.place(x=250, y=180)
        self.snxt_btn = ctk.CTkButton(self.sin_up, text="Next",bg_color='#00A7E5', fg_color='#00081F', command=self.cre_svd )
        self.snxt_btn.place(x=252, y=240)
        self.sin_up.mainloop()
        
        
    #For credentials Saving
    def cre_svd(self):
        cre_svd = CTkMessagebox(title="Credentials Saved !", message="User data has been recorder", option_1="Cont...")
    #We need to connect this message box to cont_sinup page
        
        
    #For Continue Button, Sign Up page, To show security key
    def cont_sinup(self):
        cont_su = ctk.CTk()
        cont_su.geometry('600x600')
        cont_su.title('Confidential--Security Key')
        sk1_lbl= Label(cont_su, text="Please Save and Remember your Security Key", fg='#E6A405', font=("Helvetica", 25))
        sk1_lbl.place(x=55, y=40)
        #How to display random security key
        sk2_lbl= Label(cont_su, text="This Security Key will not be shown again", fg='#E6A405', font=("Helvetica", 16))
        sk2_lbl.place(x=180, y=500)
        sk_btn=ctk.CTkButton(cont_su, text="Cont..",bg_color='#00A7E5', fg_color='#00081F', command=self.sinup_cnfrm)
        sk_btn.place(x=248, y=440)
        cont_su.mainloop()
        
        
    #For Sign Up Confirmation:
    def sinup_cnfrm():
        siup_con = CTkMessagebox(title="Sign Up", message="Sign Up Confirmed, Please Restart the Application",option_1="Done")

    #For Incorrect Security Key
    #For Forgot Password Page
    def inc_sk(self):
        # Show some retry/cancel warnings
        incsk = CTkMessagebox(title="Inncorrect Credentials!", message="Security Code Inccorect",
                            option_1="Cancel", option_2="Retry")
        if incsk.get()=='Retry':
            show_Warning("Please try again")

    #Incorrect User 
    #For Forgot Password Page
    def inc_usr(self):
        incusr = CTkMessagebox(title="Inncorrect Credentials!", message="User Not Found",
                            option_1="Ok")

    #For Menu
    def start_menu(self):
        
        self.menu = Main()
        self.menu.title('Inventory Menu')
        self.menu.geometry("600x600+10+10")
        self.menu.resizable(False,False)

        self.menu.protocol("WM_DELETE_WINDOW", self.on_closing)

        self.menu.mainloop()
        
    
    def on_closing(self):
        msg = CTkMessagebox(title="o", message="Are you sure?", option_2="yes", option_1="no")
        if msg.get() == "yes":
            self.login.deiconify()
            self.menu.destroy()

    
class Main(ctk.CTk):

        def __init__(self):
            self.geometry("1000x800+50+50")
            self.title("Inventory Manager")

if __name__ == "__main__":
    App = Inventory()

After a successful Login, the login window should minimise using self.login.withdraw() and a new window of the main application should open. On closing that window, the login window should appear again.

The problem is that calling self.menu = Main() creates an infinite recursion loop somehow.

This obviously does not happen with the following block of code in place

def start_menu(self):
        
        self.menu = ctk.CTk()
        self.menu.title('Inventory Menu')
        self.menu.geometry("600x600+10+10")
        self.menu.resizable(False,False)

        self.menu.protocol("WM_DELETE_WINDOW", self.on_closing)

        self.menu.mainloop()

But this would make the code far more cluttered which makes using classes futile.

3
  • You forget to call super().__init__() inside Main.__init__().
    – acw1668
    Commented Nov 10, 2023 at 14:52
  • I found this related question that might help you stackoverflow.com/questions/63419555/… Commented Nov 10, 2023 at 14:55
  • Thank you @acw1668 That was the mistake that I made. It is solved now! The protocol call works flawlessly.
    – Tarexino
    Commented Nov 11, 2023 at 7:15

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.