Search code examples
pythontkinterauthenticationmenubar

Login and show menu items by if


I'm trying to create a login with a tkinter Entry. Compare the input with the password and if it is correct you are supposed to get access to more stuff in the menu bar.

If I understand correctly I need to update the window in order for the menu to update, but I cant figure out how. And the variable "moberg" don't seems to update to True. Might be that one is global(?) and the other one belongs to a class. But I cant figure out how to make that work either.

Here is a sample of what I've done so far.

from tkinter import *
moberg="no"
class PCMsyntax(Frame):
    def update():
        print("updated") #only for visual, remove later
        app.mainloop.after(1, update)

    def __init__(self, master):
        super().__init__(master)
        self.pack(fill=BOTH, expand=True)
        self.initUI()


    def initUI(self):
        menubar = Menu(self.master)
        self.master.config(menu=menubar)
        syntaxMenu = Menu(menubar, tearoff=False)
        submenu = Menu(syntaxMenu)
        syntaxMenu.add_cascade(label='Arithmetic Exp', underline=0, command='')
        syntaxMenu.add_cascade(label='Assign & Compare', underline=0, command='')
        syntaxMenu.add_separator()
        syntaxMenu.add_cascade(label='Math', menu=submenu, underline=0)
        submenu.add_command(label="abs()", command='')
        if moberg == True:
            syntaxMenu.add_cascade(label='No public access', menu=submenu, underline=0)
            submenu.add_command(label="onlyForLabTech()")



        menubar.add_cascade(label="Syntax", underline=0, menu=syntaxMenu)
        menubar.add_cascade(label="Login", underline=0, command=self.onLogin)


    def onLogin(self):
        self.newWindow = Toplevel(self.master)
        self.app = Password(self.newWindow)



class Password():
    def __init__(self, master):
        self.master = master
        self.frame = Frame(self.master)
        self.pwd = Entry(self.master, width=30, bg="whitesmoke", foreground="whitesmoke")
        self.pwd.pack()
        self.verifyButton = Button(self.frame, text = 'Verify', width = 25, command = self.verify_password)
        self.verifyButton.pack()
        self.frame.pack()

    def verify_password(self):
        user_entry = self.pwd.get() 
        if str(user_entry) == "test":
            moberg=True
            print(moberg) #only for visual, remove later
            PCMsyntax.update
            self.master.destroy()
        else:
            moberg=False
            print(moberg) #only for visual, remove later
            self.master.destroy()

def main():
    root = Tk()
    root.geometry("560x600")
    app = PCMsyntax(master=root)
    app.mainloop()

if __name__ == '__main__':
    main()

Solution

  • You could achieve something like what you're looking for with the below:

    from tkinter import *
    
    class App:
        def __init__(self, root):
            self.root = root
            self.public = Frame(self.root, borderwidth=1, relief="solid") #public, visible frame
            self.hidden = Frame(self.root, borderwidth=1, relief="solid") #hidden, private frame
            self.label1 = Label(self.public, text="This text and everything over here is public.") #this is inside the public frame and so is visible
            self.entry1 = Entry(self.public) #so is this
            self.label2 = Label(self.hidden, text="This text and everything over here is hidden and only appears after login.") #this one is in the hidden frame and so is private before login
            self.button1 = Button(self.public, text="Login", command=self.command) #this is in the public frame
            self.public.pack(side="left", expand=True, fill="both") #we pack the public frame on the left of the window
            self.label1.pack() #then we pack all the widgets for both frames here and below
            self.entry1.pack()
            self.label2.pack()
            self.button1.pack()
        def command(self): #whenever the login button is pressed this is called
            if self.button1.cget("text") == "Login" and self.entry1.get() == "password": #we check if the button is in login state or not and if the password is correct
                self.hidden.pack(side="right", expand=True, fill="both") #if it is we pack the hidden frame which makes it and it's contents visible
                self.button1.configure({"text": "Logout"}) #we then set the button to a logout state
            elif self.button1.cget("text") == "Logout": #if the button is in logout state
                self.hidden.pack_forget() #we pack_forget the frame, which removes it and it's contents from view
                self.button1.configure({"text": "Login"}) #and then we set the button to login state
    
    root = Tk()
    App(root)
    root.mainloop()
    

    This is fairly self explanatory and where it isn't I've explained what's happening.

    This is just one way of many of achieving what it is you're looking for.

    I'd also like to point out that login systems are complicated and if you're looking to use this for anything serious or as a package to sell then the way I have done this is not secure.

    I'd recommend looking at other ways people handle sensitive information in tkinter.