My tkinter log in screen app has a bug that is when i click the log in button it just show the error.
from tkinter import *
from tkinter import messagebox
login_page = Tk()
login_page.title("login_page")
login_page.geometry("250x110")
def check_pass():
if username == name and userpass == password:
print("this code works")
else :
messagebox.askretrycancel(title="Try again",message="Wrong password ")
# name and password entry
log_name = Entry(login_page)
log_name.grid(row=0, column=1, pady=15)
log_pass = Entry(login_page)
log_pass.grid(row=1, column=1, pady=5)
name_label = Label(login_page, text="Name here:- ")
name_label.grid(row=0, column=0, pady=15)
password_label = Label(login_page, text="Password:- ")
password_label.grid(row=1, column=0, pady=5)
# LOG IN BUTTON
login_btn = Button(login_page, text="LOG IN", command=check_pass)
login_btn.grid(row=2, column=0, columnspan=2, ipadx=100, padx=5)
username = log_name.get()
userpass = log_pass.get()
name = "admin"
password= "admin"
mainloop()
The problem is because the username and the password variables are in the main block and when you run the code the entry boxes are empty(initially) which assigns '' to the variables. So to overcome that you should assign the variables inside the function, where now the values of the filled entry box is only taken.
Code:
from tkinter import *
from tkinter import messagebox
login_page = Tk()
login_page.title("login_page")
login_page.geometry("250x110")
def check_pass():
username = log_name.get()
userpass = log_pass.get()
if username == name and userpass == password:
messagebox.showinfo('Successfull','Login successfull')
else:
choice = messagebox.askretrycancel("Try again","Wrong password ")
if choice == True:
pass
else:
login_page.destroy()
......
# ALL THE SAME LINES OF CODE TILL
name = "admin"
password = "admin"
login_page.mainloop()
Also since your using a messagebox like askretrycancel, you can do certain action based on the choice by the user. So here I have said if the user clicks on retry, then ask them to login again, or else close the application. You can change it to whatever you like(or even remove it too.)
And also it is recommended to say login_page.mainloop(), just so that tkinter isnt confused at any later steps.
Hope your "bug" is cleared and do let me know if any errors :D
Cheers
Related
I have been working on a login page in Tkinter for fun, but I am unable to make a function that checks the entries and compares them to a specific input. Also, the code adds a messagebox and calls a function every time I exit the window.
My code is:
from tkinter import *
from tkinter import messagebox
root = Tk()
root.title("Login")
def makeUname(d):
if messagebox.askyesno("Submit?", "Is this correct?"):
global password
username = uname.get()
uname.grid_forget()
return password
def makePasswd(d):
if messagebox.askyesno("Submit?", "Is this correct?"):
global username
password = uname.get()
passwd.grid_forget()
return username
def button():
makeUname("")
makePasswd("")
quitbutt.grid_forget()
uname = Entry(root)
uname.grid(row=1, column=1)
passwd = Entry(root, show="*")
passwd.grid(row=2, column=1)
quitbutt = Button(root, text="Login", command=button)
quitbutt.grid(row=3, column=1, columnspan=2, sticky='nesw')
root.mainloop()
makeUname("")
makePasswd("")
if(username == "username" and password == "password"):
messagebox.showwarning("Warning", "Sorry, this isn't programmed yet.")
else:
messagebox.showwarning("Nope", "Nope. Nice try.")
Can someone help me with my code? Should I use a different setup or method?
There was many problem so I changed all to make it simpler.
I added comments in code to explain some elements.
from tkinter import *
from tkinter import messagebox
# --- functions ---
def button():
# use global variable (instead of local variables)
# to keep username, password outside function and keep after closing window
global username
global password
username = uname.get()
password = passwd.get()
#print('button:', username, password)
if username == "username" and password == "password":
messagebox.showwarning("Warning", "Sorry, this isn't programmed yet.")
root.destroy() # close window
else:
messagebox.showwarning("Nope", "Nope. Nice try.")
# window still open
# --- main ---
# default values at start
# Someone can exit window without using Button
# and it would not create this variables in button()
username = ""
password = ""
root = Tk()
root.title("Login")
uname = Entry(root)
uname.grid(row=1, column=1)
passwd = Entry(root, show="*")
passwd.grid(row=2, column=1)
quitbutt = Button(root, text="Login", command=button)
quitbutt.grid(row=3, column=1, columnspan=2, sticky='nesw')
# start program (start engine, display window, (re)draw widgets, handle events, get events from system (keyboard, mouse), send events to widgets)
root.mainloop()
# after closing window this variables still have values from window
print("after mainloop:", username, password)
i'm new to tkinter and wanted to change an already existing piece of code I made into GUI. The piece of code below is a username and password system. The thing I need help with is that I can not figure out how to get a new box or to remove the widgets of the gui. Nothing is wrong with the code below but I wanted to show you as it shows you how I've coded it and how to make a new box based on this code.
Btw I am in python 3.5.1 and on windows 10.
import tkinter
from tkinter import *
import tkinter.messagebox as box
import time
def dialog1():
username=entry1.get()
password = entry2.get()
if (username == 'Noel' and password == 'Music quiz'):
box.showinfo('info','You may now enter the Music quiz')
else:
box.showinfo('info','Invalid Login')
window = Tk()
window.title('Music quiz')
window.geometry("300x125")
window.wm_iconbitmap('Favicon.ico')
frame = Frame(window)
Label1 = Label(window,text = 'Username:')
Label1.pack()
entry1 = Entry()
entry1.pack()
Label2 = Label(window,text = 'Password: ')
Label2.pack()
entry2 = Entry()
entry2.pack()
Here is edited code that I think will do what you have asked. Explanations are in the code in the form of comments.
import tkinter
from tkinter import *
import tkinter.messagebox as box
import time
def dialog1():
username=entry1.get()
password = entry2.get()
if (username == 'Noel' and password == 'Music quiz'):
box.showinfo('info','You may now enter the Music quiz')
loginframe.destroy() #remove the login frame
##code to create the quiz goes here##
else:
box.showinfo('info','Invalid Login')
window = Tk()
window.title('Music quiz')
window.geometry("300x125")
window.wm_iconbitmap('Favicon.ico')
loginframe = Frame(window) #create an empty frame for login
loginframe.pack() #put the empty frame into the window
#all elements below are put into the 'loginframe' Frame
Label1 = Label(loginframe,text = 'Username:')
Label1.pack()
entry1 = Entry(loginframe)
entry1.pack()
Label2 = Label(loginframe,text = 'Password: ')
Label2.pack()
entry2 = Entry(loginframe)
entry2.pack()
donebttn = Button(loginframe, text='Done',
command=dialog1) #create a button to continue
donebttn.pack() #display that button
mainloop()
So I'm not new to python or programing in general, but am still learning with python. I am working on a program for me and some of my friends. and I was making the GUI, and code, for the login screen, when I kept getting this syntax error for one of my functions. And I have no idea as to what may be causing it. If someone could provide some assistance it would be greatly appreciated. p.s. I'll only be posting the part I've been having an error with, and only what is, or that I feel, is necessary to help show what's going on, and I'm using python 3.x if that helps.
# Login Setup
loginW = Tk()
# Password Authentication Function
def Authentication():
valid = 'pythonprogramming'
if (pwordE = valid):
# Syntax Error for the above line
mp = Tk()
loginW.destroy()
# Main Program here
mp.mainloop()
else:
errorW = Tk()
errorL = Label(errorW, text='Invalid Password!')
errorW.mainloop()
pwordL = Label(loginW, text='Password: ')
pwordE = Entry(loginW, show='*')
logBtn = Button(loginW, text='Login')
logBtn.bind("<Button-1>", Authentication)
pwordL.pack(row=0)
pwordE.pack(row=0, column=1)
logBtn.pack(row=1, columnspan=2)
loginW.mainloop()
Your code has several errors:
Change pack to grid.
change pwordE = valid to pwordE.get() == valid
add argument event to Authentication function
complete code:
# Login Setup
loginW = Tk()
# Password Authentication Function
def Authentication(event):
valid = 'pythonprogramming'
if pwordE.get() == valid:
# Syntax Error for the above line
mp = Tk()
loginW.destroy()
# Main Program here
mp.mainloop()
else:
errorW = Tk()
errorL = Label(errorW, text='Invalid Password!')
errorL.grid(row=0, column=0)
errorW.mainloop()
pwordL = Label(loginW, text='Password: ')
pwordE = Entry(loginW, show='*')
logBtn = Button(loginW, text='Login')
logBtn.bind("<Button-1>", Authentication)
pwordL.grid(row=0, column=0)
pwordE.grid(row=0, column=1)
logBtn.grid(row=1, columnspan=2)
loginW.mainloop()
Screenshots:
Correct Password:
Incorrect Password:
I want to have a login window pop up at first, then once the conditions are satisfied, it closes the login window and opens a new window.
from Tkinter import *
import tkMessageBox
#Not really sure what i'm doing here anymore
while True:
Login = Tk()
Login.title('Login')
Login.geometry('400x130')
NameLabel = Label(Login, text='Username')
NameLabel.place(bordermode=OUTSIDE, height=25, width=100, x=100)
NameEntryRaw = Entry(Login)
NameEntryRaw.place(bordermode=OUTSIDE, height=25, width=100, x=200)
CodeLabel = Label(Login, text='Code')
CodeLabel.place(bordermode=OUTSIDE, height=25, width=100, x=100, y=30)
CodeEntryRaw = Entry(Login)
CodeEntryRaw.place(bordermode=OUTSIDE, height=25, width=100, x=200, y=30)
def tbd():
tkMessageBox.showinfo('Congrats!', 'This program is not done yet')
def login():
Usernames=list()
Usernames.append('Mordecai')
Usernames.append('Ezekiel')
Usernames.append('Goliath')
Usernames.append('Abraham')
Usernames.append('Bartholomew')
Usernames.append('Jedediah')
Usernames.append('Solomon')
Usernames.append('Tobias')
Usernames.append('Yohanan')
Usernames.append('Lucifer')
NameEntry=NameEntryRaw.get()
CodeEntry=CodeEntryRaw.get()
CodeReal='116987'
if Usernames.count(NameEntry) == 0:
tkMessageBox.showinfo('Error!', 'Your Username is invalid! Try Again.')
else:
()
if CodeEntry != CodeReal:
tkMessageBox.showinfo('Error!', 'The Code entered is invalid! Try Again.')
else:
()
LoginButton = Button(Login, text="Login", command=login)
LoginButton.place(bordermode=OUTSIDE, height=50, width=200, x=100, y=60)
Login.mainloop()
else:
DataBase = Tk()
#this will be the data base
DataBase.mainloop()
You don't want to use two mainloop's. Generally speaking, your tkinter app should have a single .mainloop called.
As for how to get the login popup and then switch to the window... You can create your root window with the app and when you start your program have a Toplevel window be shown with the login stuff, maybe hide / withdraw the root additionally?, have the toplevel have a submit button or something that would validate the credentials. If the credentials are valid, then you can use the destroy() method and remove the toplevel widget / go to the root window for your main app.
Having a while True repeat the process of creating a GUI + mainloop is bad for obvious reasons.
Edit: static is probably a bad term for a mutable object, since it's mutable... Added tuple vs list for global.
You don't need to create a blank list and then use append to add your usernames to the usernames list. You can make this global. Since, username is a mutable object (it's a list) you could still perform operations elsewhere in your code on this global, say .append etc. Or, if you never have these change i'd make it a tuple, since they're immutable and this "fits" better with the intent.
Instead of using .count(*) to get the occurrences of an element in a list you can just use:
if (object) in (some list) #Object is an abstraction, not the type
If CodeReal is static, which it looks to be, you can also make this global.
Here's a quick edit to your code, you can do this without classes, but I used classes here to try to distinctly show the logical separation in the program.
I changed a few variable names as well, so that it was easier to read / understand. I also used .pack() and .grid() as this was quicker to code than having to use .place() everywhere this is an arbitrary choice.
import Tkinter as tk
import tkMessageBox as messagebox
import sys
#No need to do usernames = list() and then .append for each one.
#Just make a global list holding them all...
USERNAMES = ('Mordecai', 'Ezekiel', 'Goliath', 'Abraham', 'Bartholomew',
'Jedediah', 'Solomon', 'Tobias', 'Yohanan', 'Lucifer')
PASSWORD = '116987' #Was CodeReal, this can be global
#We overrode the closing protocol here.
def closing_protocol():
if messagebox.askokcancel("Quit", "Do you want to quit?"):
sys.exit()
#A container for our Login "app".
class Login(tk.Toplevel):
def __init__(self, *args, **kwargs):
#We init the toplevel widget.
tk.Toplevel.__init__(self, *args, **kwargs)
#We set the closing protocol to be the overridden version / func.
self.wm_protocol("WM_DELETE_WINDOW", closing_protocol)
tk.Label(self, text='Username').grid(row=0, column=0)
self.username = tk.Entry(self)
self.username.grid(row=0, column=1)
tk.Label(self, text='Password').grid(row=1, column=0)
#Show = '*' just hides the password instead of plain-text like
#you typically see
self.password = tk.Entry(self, text='Password', show='*')
self.password.grid(row=1, column=1)
#When the button is clicked the _callback function will be called
tk.Button(self, text='Login', command=self._callback).\
grid(row=2, column=0, columnspan=2, sticky="nsew")
def _callback(self):
#If the username or password is bad, raise an error message.
if (self.username.get() not in USERNAMES or
self.password.get() != PASSWORD):
messagebox.showerror("Validation Error!",
"You have entered invalid credentials.\n" +
"Please try again.")
#otherwise, we're good to go. Destroy login / show main app.
else:
root.deiconify()
app.pack()
self.destroy()
class Main(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
tk.Label(self, text="MAIN APP STUFF").pack()
if __name__ == '__main__':
root = tk.Tk()
root.withdraw() #Hides the root window initially.
app = Main(root)
Login()
root.mainloop()
I want to thank you for clarifying what you did for me. It proved to be very helpful! Here is what I've settled with. I put the names back and made it to work without classes, as I found it a little too difficult to work with.
from Tkinter import *
import tkMessageBox
import sys
import binascii #Not for this part
Codenames = ['Mordecai', 'Ezekiel', 'Goliath', 'Abraham', 'Bartholomew',
'Jedediah', 'Solomon', 'Tobias', 'Yohanan', 'Lucifer']
Password = '116987'
def close_protocol():
if tkMessageBox.askokcancel("Quit", "Do you want to quit?"):
sys.exit()
#Below for a later part...
def text_to_bits(text, encoding='utf-8', errors='surrogatepass'):
bits = bin(int(binascii.hexlify(text.encode(encoding, errors)), 16))[2:]
return bits.zfill(8 * ((len(bits) + 7) // 8))
def text_from_bits(bits, encoding='utf-8', errors='surrogatepass'):
n = int(bits, 2)
return int2bytes(n).decode(encoding, errors)
def int2bytes(i):
hex_string = '%x' % i
n = len(hex_string)
return binascii.unhexlify(hex_string.zfill(n + (n & 1)))
#Above for a later part...
SDB = Tk()
SDB.title("SMEGJALBYT DATA BASE")
SDB.withdraw()
SDBLogin = Toplevel()
SDBLogin.title("Login")
SDBLogin.wm_protocol("WM_DELETE_WINDOW", close_protocol)
CodenameLabel = Label(SDBLogin, text="Codename")
CodenameLabel.grid(row=0, column=0)
CodenameEntry = Entry(SDBLogin)
CodenameEntry.grid(row=0, column=2)
PasswordLabel = Label(SDBLogin, text="Password")
PasswordLabel.grid(row=1, column=0)
PasswordEntry = Entry(SDBLogin, show='*')
PasswordEntry.grid(row=1, column=2)
def login_operation():
if CodenameEntry.get() not in Codenames:
tkMessageBox.showinfo("INVALID CODENAME!", "Please verify input in the 'Codename' field")
elif PasswordEntry.get() != Password:
tkMessageBox.showinfo("INVALID PASSWORD!", "Please verify input in the 'Password' field")
else:
SDB.deiconify()
SDBLogin.destroy()
LoginButton = Button(SDBLogin, text="Login", command=login_operation)
LoginButton.grid(row=2, column=1)
#Code continues...
#Code finisles....
SDB.mainloop()
This has the same basic functionality, just organised the way I wanted it.
I have created a variety of Tkinter widgets with for loops. All of them remove fine, except for the "lock_btn" widget. When I press that button the lock button stays on the page (although the rest of the code in the function works). I have tried both with and without globals (the code you see includes globals).
import tkinter
import tkinter.messagebox
#Setting properties for the window
window = tkinter.Tk()
window.title("Shutdown Timer")
window.geometry("250x300")
window.configure(background="black")
def Login():
for x in range(0,5):
login_window[x].pack_forget()
def Auth():
if usr.get() == "isensedemons":
if pas.get() == password:
Login()
else:
tkinter.messagebox.showinfo("Login Error", "Incorrect Username or Password")
else:
tkinter.messagebox.showinfo("Login Error", "Incorrect Username or Password")
def Lock():
global lock_btn
for x in range(0,1):
lock_btn.pack_forget()
for x in range(0,5):
login_window[x].pack()
lock_btn = tkinter.Button(window, text="Lock", fg="white", bg="black", command=Lock)
lbl_usr = tkinter.Label(window, text="Username", fg="white", bg="black")
usr = tkinter.Entry(window)
lbl_pas = tkinter.Label(window, text="Password", fg="white", bg="black")
pas = tkinter.Entry(window, show="•")
btn = tkinter.Button(window, text="Authenticate", fg="white", bg="black", command=Auth)
password = "password"
login_window = [lbl_usr,usr,lbl_pas,pas,btn]
class Create():
lock_btn.pack()
lock_btn.place(rely=1, relx=1, anchor="se")
Create()
#Starts the Program
window.mainloop()
You start by calling lock_btn.pack(0), then you switch to using place(...). So, the widget is being managed by place because it can be only managed by one geometry manager. When you call pack_forget it has no effect because pack isn't in control of the widget.