Hey I´m working on Tkinter GUIs and I´ve been trying to make a Login Form with Password and Username. I´m trying to link/connect the user and passw variables to the two tk.Entry() elements (username and password). I want to link/connect them so I can make a function where the program asks the function if the password and username is correct and if your allowed to login (if username == "" and password == "": login() )
Here is my code:
import tkinter as tk
from tkinter import *
root = tk.Tk()
root.title("Login")
root.resizable(False, False)
global username
username = StringVar
global password
password = StringVar
user = username.get()
passw = password.get()
tk.Label(root, text="Please enter details below", height=1,width=20).pack()
tk.Label(root, text="Username *", height=1,width=20).pack()
tk.Entry(root, textvariable=username).pack()
tk.Label(root, text="Password *", height=1,width=20).pack()
tk.Entry(root, textvariable=password).pack()
tk.Button(root, text="Login", height=2, width=20, command=login).pack()
root.mainloop()
The error I get:
Traceback (most recent call last): File "C:\Users\Martin\AppData\Local\Programs\Python\Python38-32\lib\tkinter__init__.py", line 1883, >in call return self.func(*args) TypeError: login() missing 1 required positional argument: 'self'
You are missing a few key elements.
StringVar
is missing ()
. You must have the parenthesis for these to work as expected.
Your button command is trying to activate something that does not exist. That also makes it very puzzling that you are getting the error your have posted. You should be getting name 'login' is not defined
.
No need to do from tkinter import *
you are already using import tkinter as tk
.
username.get()
and password.get()
will always be an empty string because this is only called once at the instance the program starts. They need to be in a function to be updated.
Your use of global
is doing nothing for you. The term global
is used to tell a local namespace (IE inside a function) that the variable name in question is to be defined in the global namespace and accessible in the global namespace. Right now you are telling the global name space it can find something in the global name space. That is pointless.
Cleaned up code:
import tkinter as tk
root = tk.Tk()
root.title("Login")
root.resizable(False, False)
username = tk.StringVar()
password = tk.StringVar()
def login():
user = username.get()
passw = password.get()
if user == 'me' and passw == 'pass':
print('Login success!')
else:
print('Login failed!')
tk.Label(root, text="Please enter details below", height=1, width=20).pack()
tk.Label(root, text="Username *", height=1, width=20).pack()
tk.Entry(root, textvariable=username).pack()
tk.Label(root, text="Password *", height=1, width=20).pack()
tk.Entry(root, textvariable=password).pack()
tk.Button(root, text="Login", height=2, width=20, command=login).pack()
root.mainloop()