How to close multiple Tkinter windows with one button - python

I am trying to build a python application. The first UGI is requesting the username and password. Then a second tk window pops up if login is successful with an okay button. Once then user press the okay button, both tk windows (the one requesting username and password and the login successful msg window) will disappear and the program continues to run.
I am very stuck with being able to press the okay button and close "both" windows. Any insights will be appreciated, thank you!
All the codes seem to be working fine. the command to execute function LoginSuccessful within the CheckLogin is able to execute the print("ANCD") but it doesn't close the two tk windows.
#import packages
import time
import openpyxl
from openpyxl import load_workbook
import tkinter as tk
from tkinter import *
import sys
def Function():
global user1
user1 = 'testing'
password1 = '0000'
def Login_form():
global username
global password
global rootA
rootA = Tk()
rootA.title('User Authentication')
msgbox1 = Label(rootA, text='Please Login\n')
msgbox1.grid(sticky=E)
username = Label(rootA, text='Username: ')
password = Label(rootA, text='Password: ')
username.grid(row=1, sticky=W)
password.grid(row=2, sticky=W)
username = Entry(rootA)
password = Entry(rootA, show='*')
username.grid(row=1, column=1)
password.grid(row=2, column=1)
login_btn = Button(rootA, text='Login', command=CheckLogin)
exit_btn=Button(rootA, text='Exit',command=sys.exit)
login_btn.grid(row=4, column=1)
exit_btn.grid(row=4, column=2)
rootA.mainloop()
def CheckLogin():
if username.get() == user1 and password.get() == password1:
rootA = Tk()
rootA.title('Authentication Cehck')
rootA.geometry('150x100') # Makes the window a certain size
rlbl = Label(rootA, text='\n Logged In')
okay_btn=Button(rootA, text='Okay',command=LoginSuccessful)
okay_btn.pack()
#LoginSuccessful()
else:
r = Tk()
r.title('Authentication Cehck')
r.geometry('150x160')
rlbl = Label(r, text='\n Invalid Login')
rlbl.pack()
okay_btn=Button(r, text='Try Again',command=r.destroy)
okay_btn.pack()
exit_btn=Button(r, text='Exit',command=sys.exit)
exit_btn.pack()
#r.mainloop()
def LoginSuccessful ():
rootA.destroy
print("ANCD")
def Insert_Rows():
for rows in range (len(All_Users_Sheet)):
if rows == 0:
rows +1
continue
if All_Users_Sheet[rows][10].value == None:
break
else:
print(All_Users_Sheet[rows][10].value)
print(type(All_Users_Sheet[rows][10].value))
Login_form()
Function()
Is there any way that after checking the username and password, if it's correct, close all tk windows by pressing a button and continue running the remaining tasks?

You should only create one instance of Tk. If you needed additional window, use Toplevel instead.
def CheckLogin():
if username.get() == user1 and password.get() == password1:
rootA = Toplevel()
rootA.title('Authentication Check')
...
else:
r = Toplevel()
...

i got one solution.
from tkinter import *
global user1
user1 = 'testing'
password1 = '0000'
def combine_funcs(*funcs):
def combined_func(*args, **kwargs):
for f in funcs:
f(*args, **kwargs)
return combined_func
def Login_form():
global username
global password
global rootA
rootA = Tk()
rootA.title('User Authentication')
msgbox1 = Label(rootA, text='Please Login\n')
msgbox1.grid(sticky=E)
username = Label(rootA, text='Username: ')
password = Label(rootA, text='Password: ')
username.grid(row=1, sticky=W)
password.grid(row=2, sticky=W)
username = Entry(rootA)
password = Entry(rootA, show='*')
username.grid(row=1, column=1)
password.grid(row=2, column=1)
login_btn = Button(rootA, text='Login', command=CheckLogin)
exit_btn=Button(rootA, text='Exit',command=rootA.destroy)
login_btn.grid(row=4, column=1)
exit_btn.grid(row=4, column=2)
rootA.mainloop()
def CheckLogin():
global rootA
if username.get() == user1 and password.get() == password1:
rootA = Tk()
rootA.title('Authentication Cehck')
rootA.geometry('150x100') # Makes the window a certain size
rlbl = Label(rootA, text='\n Logged In')
okay_btn=Button(rootA, text='Okay',command=LoginSuccessful)
okay_btn.pack()
#LoginSuccessful()
else:
r = Tk()
r.title('Authentication Cehck')
r.geometry('150x160')
rlbl = Label(r, text='\n Invalid Login')
rlbl.pack()
okay_btn=Button(r, text='Try Again',command=r.destroy)
okay_btn.pack()
exit_btn=Button(r, text='Exit',command= combine_funcs(rootA.destroy, r.destroy))
exit_btn.pack()
#r.mainloop()
def LoginSuccessful ():
rootA.destroy
print("ANCD")
def Insert_Rows():
for rows in range (len(All_Users_Sheet)):
if rows == 0:
rows +1
continue
if All_Users_Sheet[rows][10].value == None:
break
else:
print(All_Users_Sheet[rows][10].value)
print(type(All_Users_Sheet[rows][10].value))
Login_form()
please dont't ask about def combine_funcs(*funcs):
def combined_func(*args, **kwargs):
for f in funcs:
f(*args, **kwargs)
return combined_func
,it just solves the problem

Related

How do i move to another section of my program?

I have built a login system using Tkinter and Sqlite3 for Python and I need to move on to another section of code once the login flow is complete. At the point in the 'test' function where I've added a comment, I need a separate python file (eg somefile.py) to run its code. How is best to do this? Your help is appreciated! Code below:
from tkinter import *
import Check_credentials as check
import New_user_screen as create
def test():
username = user.get()
password = pword.get()
global valid
valid = False
valid=check.check_user(username,password)
print(valid)
if valid == True:
login.destroy()
'launch main program' #Here is where i need the next section of the program to be run but ideally not as another function in this proram
print('Incorrect login getails\nPlease try again!')
def screen():
global login
login = Tk()
login.title('User Login')
login.geometry('300x180')
login.configure(background = 'white')
global user
global pword
message = Label(login,
text = 'Please enter username and password below',
bg='white')
message.pack()
label1 = Label(login,
text = 'Username',
bg='white')
label1.place(x=0,y=50)
user = Entry(login)
user.place(x=100,y=50)
label2 = Label(login,
text = 'Password',
bg='white')
label2.place(x=0,y=90)
pword = Entry(login)
pword.place(x=100,y=90)
confirm = Button(login,
text='Sign In',
fg='white',
bg='blue',
command = test)
confirm.place(x=50,y=130)
new = Button(login,
text='New User',
fg='white',
bg='blue',
command = create.screen)
new.place(x=120,y=130)
When the login is valid, it will go to the the function greeting in the class Main
from tkinter import *
import Check_credentials as check
import New_user_screen as create
class Login:
def test():
username = user.get()
password = pword.get()
global valid
valid = False
valid=check.check_user(username,password)
print(valid)
if valid == True:
login.destroy()
Main.greeting() #Here is where i need the next section of the program to be run but ideally not as another function in this proram
def screen():
global login
login = Tk()
login.title('User Login')
login.geometry('300x180')
login.configure(background = 'white')
global user
global pword
message = Label(login,
text = 'Please enter username and password below',
bg='white')
message.pack()
label1 = Label(login,
text = 'Username',
bg='white')
label1.place(x=0,y=50)
user = Entry(login)
user.place(x=100,y=50)
label2 = Label(login,
text = 'Password',
bg='white')
label2.place(x=0,y=90)
pword = Entry(login)
pword.place(x=100,y=90)
confirm = Button(login,
text='Sign In',
fg='white',
bg='blue',
command = test)
confirm.place(x=50,y=130)
new = Button(login,
text='New User',
fg='white',
bg='blue',
command = create.screen)
new.place(x=120,y=130)
class Main:
def greeting():
print("You Have Logged In Successfully")

I dont know how to fix this error: TypeError: authenticate_name() missing 1 required positional argument: 'eUsername'

Here's my entire code:
import tkinter as tk
from tkinter import *
import turtle
file = open("usernames.txt", "r+")
file2 = open("passwords.txt", "r+")
def mainScreen():
mainScreen = Tk()
mainScreen.geometry("250x175")
mainScreen.title("Login Screen")
Label(text = "Please select an option.").pack()
Label(text = "").pack()
Button(text = "Login into an existing account.", command = login).pack()
Label(text = "").pack()
Button(text = "Create a new account.").pack()
mainScreen.mainloop()
def login():
loginScreen = Tk()
loginScreen.geometry("200x150")
loginScreen.title("Existing Account Login")
Label(loginScreen,text = "Please enter your username.").pack()
eUserName = StringVar()
userEntry = Entry(loginScreen, textvariable = eUserName)
userEntry.pack()
eUserName = userEntry.get()
Label(loginScreen,text = "Please enter your pasword.").pack()
ePassWord = StringVar()
passEntry = Entry(loginScreen, textvariable = ePassWord)
passEntry.pack()
ePassWord = passEntry.get()
Label(text="").pack()
Button(loginScreen, text = "Click to login.", command = authenticate_name).pack()
return ePassWord, eUserName
def authenticate_name(eUsername):
usernames = []
validCheck = False
for line in file:
usernames.append(line)
for eUserName in usernames:
if eUserName in usernames:
validCheck = True
pass
else:
tkMessageBox.showerror("Invalid Username!", "This usernames is invalid!")
exit()
def authenticate_password():
passwords = []
for line in file2:
passwords.append(line)
for count in range(len(passwords)):
count += 1
if ePassWord in passwords:
game()
else:
tkMessageBox.showerror("Invalid Password!", "This password is incorrect!")
mainScreen()
The error I get is the following:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Vlad\AppData\Local\Programs\Python\Python37-32\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
TypeError: authenticate_name() missing 1 required positional argument: 'eUsername'
I don't know how to fix this. I've tried doing an str() function on eUsername and that didn't seen to work.
Any help would be greatly appreciated!
You're using a number of features of (Python 3) tkinter incorrectly, including StringVar, messagebox, top level windows, etc. By making your StringVar variables global, and reworking your logic, I've come up to this approximation to what you're trying to implement:
from tkinter import *
from tkinter import messagebox
def mainScreen():
Label(text="Please select an option.").pack()
Label(text="").pack()
Button(text="Login into an existing account.", command=login).pack()
Label(text="").pack()
Button(text="Create a new account.").pack()
def login():
loginScreen = Toplevel(root)
loginScreen.geometry("200x150")
loginScreen.title("Existing Account Login")
Label(loginScreen, text="Please enter your username.").pack()
Entry(loginScreen, textvariable=eUserName).pack()
Label(loginScreen, text="Please enter your password.").pack()
Entry(loginScreen, textvariable=ePassWord).pack()
Label(text="").pack()
Button(loginScreen, text="Click to login.", command=authenticate_name).pack()
def authenticate_name():
with open("usernames.txt") as file:
for username in file:
if eUserName.get() == username.strip():
authenticate_password()
return
messagebox.showerror("Invalid Username!", "This username is invalid!")
exit()
def authenticate_password():
with open("passwords.txt") as file:
for password in file:
if ePassWord.get() == password.strip():
game()
return
messagebox.showerror("Invalid Password!", "This password is incorrect!")
exit()
def game():
messagebox.showinfo("You're In!", "The game has begun!")
root = Tk()
root.geometry("250x175")
root.title("Login Screen")
eUserName = StringVar()
ePassWord = StringVar()
mainScreen()
root.mainloop()

Tkinter not removing a Label widget

I am relatively new to this, but is anyone able to find out why errorLabel is not forgetting? I do not see the reason as to why this would be the case. All of the other widgets disappear, but not the errorLabel.
def checkLogin(root, username, password, userNameLabel, userNameEntry, passwordLabel, passwordEntry, loginButton):
print(gui.checkUser(username, password))
errorLabel = Label(root, text="")
errorLabel.pack()
if (gui.checkUser(username, password)):
userNameLabel.forget()
errorLabel.forget()
userNameEntry.forget()
passwordLabel.forget()
passwordEntry.forget()
loginButton.forget()
else:
errorLabel.config(text="Error, that is an incorrect username and/or password")
This is whole code
class gui:
def checkUser(username, password):
data = musicQuiz.getUsers()
for usernameDB, passwordDB in data:
if str(usernameDB) == str(username) and str(passwordDB) == str(password):
return True
return False
def checkLogin(root, username, password, userNameLabel, userNameEntry, passwordLabel, passwordEntry, loginButton):
print(gui.checkUser(username, password))
errorLabel = Label(root, text="")
errorLabel.pack()
if (gui.checkUser(username, password)):
userNameLabel.forget()
errorLabel.forget()
userNameEntry.forget()
passwordLabel.forget()
passwordEntry.forget()
loginButton.forget()
else:
errorLabel.config(text="Error, that is an incorrect username and/or password")
def login(root):
userNameLabel = Label(root, text="Username")
userNameEntry = Entry(root)
passwordLabel = Label(root, text="Password")
passwordEntry = Entry(root)
loginButton = Button(root, text = "Login!", command=lambda: gui.checkLogin(root, userNameEntry.get(), passwordEntry.get(), userNameLabel, userNameEntry, passwordLabel, passwordEntry, loginButton))
userNameLabel.pack()
userNameEntry.pack()
passwordLabel.pack()
passwordEntry.pack()
loginButton.pack()
def main():
musicQuiz.setupSQL()
root = Tk()
root.geometry("350x350")
gui.login(root)
root.mainloop()
if __name__ == "__main__":
gui.main()

Change password of login page with tkinter

I'm trying to make a login gui using tkinter, and I want a new window to open when I click on change password.
When the window opens it should prompt the user for a new password, and then change and store the password. Afterwards, it should login again using the changed password.
import tkinter as tk
import tkinter.messagebox as tm
class LoginFrame(tk.Frame):
storedPassword='password'
def __init__(self, master):
super().__init__(master)
#storedPassword='password'
self.label_username = tk.Label(self, text="Username")
self.label_password = tk.Label(self, text="Password")
self.entry_username = tk.Entry(self)
self.entry_password = tk.Entry(self)#, show="*") to help us see new password
self.label_username.grid(row=0)
self.label_password.grid(row=1)
self.entry_username.grid(row=0, column=1)
self.entry_password.grid(row=1, column=1)
self.logbtn = tk.Button(self, text="Login", command=self._login_btn_clicked)
self.logbtn.grid(columnspan=2)
newPassword = self.entry_password.get()
print(newPassword)
self.logbtn = tk.Button(self, text="change_password", command=self.change_password)
self.logbtn.grid(columnspan=2)
def change_password(self,newPassword):
self.new_password = tk.Label(self, text="new password")
self.entry_newpassword = tk.Entry(self)
self.storedPassword=newPassword
print(self.entry_newpassword.get())
def _login_btn_clicked(self):
username = self.entry_username.get()
password = self.entry_password.get()
if username == "admin":
if password == self.storedPassword:
tm.showinfo("Login info", "Welcome admin")
self.storedPassword=self.entry_password.get()
else:
tm.showerror("Login error", "Incorrect password")
else:
tm.showerror("Login error", "Incorrect username")
window= tk.Tk()
lf = LoginFrame(window)
#root = tk.Tk()
#newWindow= LoginFrame(root)
#root.mainloop()
window.mainloop()
Simply destroy the initial window first using window.destroy() and then create a new window in a function when it is called by the button. Continue adding entry widgets and labels as you know and get the new password and run another function to go back to initial page after using root.destroy() to remove change password window.
Here is a simple code showing what I just said:
from tkinter import *
from tkinter import messagebox
storedPassword = 'password'
def loginok(username,password):
global storedPassword
if username == "admin":
if password == storedPassword:
messagebox.showinfo("Login Successful!","Welcome Admin")
else:
messagebox.showerror("Login Failed!","Wrong Password")
else:
messagebox.showerror("Login Failed!","Wrong Username")
def cpass():
global window
window.destroy()
window = Tk()
Label(window,text="Enter new password:").pack()
passn = Entry(window,width=15)
passn.pack()
Button(window,text="OK",command=lambda:chgpass(passn.get())).pack()
window.mainloop()
def chgpass(newpass):
global window
global storedPassword
storedPassword = newpass
window.destroy()
login()
def login():
global window
window = Tk()
Label(window,text="Username:").pack()
usern = Entry(window,width=15)
usern.pack()
Label(window,text="Password:").pack()
passw = Entry(window,width=15,show="*")
passw.pack()
Button(window,text="Login",command=lambda:loginok(usern.get(),passw.get())).pack()
Button(window,text="Forgot",command=cpass).pack()
window.mainloop()
login()

how to put default text on tkinter's entry widget

so, i opened a question about it yesterday but it got closed saying its a dupe, let me explain my question more specificly then, hoping im not passinng any law here..
im trying to set a default message that will be set as gray and low opacity in the entry widget on tkinter, that after being focused in will dispear.
i managed to do that, but i got into a problem.
the default text is "enter username" for example, but if someone tries to do this user name it says that the username entry is empty which isnt what i wanna do..
i hope you understood my question.
edit: my question is how to do a placeholder text, while allowing the user to input the same text as the placeholder.
thanks in advance, this is my code:
from tkinter import *
from tkinter import messagebox
main = Tk()
main.title("ani gever")
checkbox_var = IntVar()
def delete_user_default(event):
if User_entry.get()!="enter username":
pass
else:
User_entry.delete(0, END)
def delete_password_default(event):
if password_entry.get() !="insert password":
pass
else:
password_entry.delete(0, END)
password_entry.config(show="*")
def return_user_default(event):
if User_entry.get()=="":
User_entry.insert(0, "enter username")
emptyuser=1
else:
pass
def return_password_default(event):
if password_entry.get()=="":
password_entry.insert(0,"insert password")
password_entry.config(show="")
else:
pass
def details(event):
if ((User_entry.get() == "enter username") or (password_entry.get() == "insert password")):
errorLabel.config(text="Username or password is empty!",fg="red")
elif ((" " in User_entry.get()) or " " in password_entry.get()):
errorLabel.config(text="dont use spaces in your password or username!", fg="red")
else:
print ("username:" + User_entry.get() + "\npassword:" + password_entry.get())
errorLabel.config(text="")
#============== define texts=======================
User_label= Label(main,text="Username:")
password_label= Label(main,text="Password:")
User_entry = Entry(main)
password_entry= Entry(main,show="*")
enterButton= Button(main,text="Log in")
errorLabel= Label(main,text="")
#=============default text on entry's=============
password_entry.config(show="")
User_entry.insert(0,"enter username")
password_entry.insert(0,"insert password")
User_entry.bind("<FocusIn>",delete_user_default)
password_entry.bind("<FocusIn>",delete_password_default)
User_entry.bind("<FocusOut>",return_user_default)
password_entry.bind("<FocusOut>",return_password_default)
#=============return user details ===========
User_entry.bind("<Return>",details)
password_entry.bind("<Return>",details)
enterButton.bind("<Button-1>",details)
#=============place everything on screen===========
User_label.grid(row=0,sticky= W)
User_entry.grid(row=0,column=1,sticky= W)
password_label.grid(row=1,sticky= W)
password_entry.grid(row=1,column=1,sticky= W)
enterButton.grid(row=2,sticky=W)
errorLabel.grid(row=3,columnspan=10,sticky= W)
main.mainloop()
Using this answer an is_empty function can be created. It prints True if validated entry is 'empty' and False if not.
import tkinter as tk
class EntryWithPlaceholder(tk.Entry):
def __init__(self, master=None, placeholder="PLACEHOLDER", color='grey'):
super().__init__(master)
self.placeholder = placeholder
self.placeholder_color = color
self.default_fg_color = self['fg']
self.bind("<FocusIn>", self.foc_in)
self.bind("<FocusOut>", self.foc_out)
self.put_placeholder()
def put_placeholder(self):
self.insert(0, self.placeholder)
self['fg'] = self.placeholder_color
def foc_in(self, *args):
if self['fg'] == self.placeholder_color:
self.delete('0', 'end')
self['fg'] = self.default_fg_color
def foc_out(self, *args):
if not self.get():
self.put_placeholder()
def is_empty(widget, empty_color):
if widget.get():
if widget['fg'] == empty_color:
print (True)
else:
print (False)
else:
print (True)
if __name__ == "__main__":
root = tk.Tk()
username = EntryWithPlaceholder(root, "username")
password = EntryWithPlaceholder(root, "password", 'blue')
username.pack()
password.pack()
tk.Button(root, text="Validate",
command=lambda wid=username, clr=username.placeholder_color:
is_empty(wid, clr)).pack()
root.mainloop()

Categories