I've reorganised my question.
I have a two windows(in two different .py files) in one project built on Tkinter:
- Login/Security UI which takes login and password. There is a "Login" button linked to the class' method which checks the name/pass pair and returns True if login data is correct
- Main app UI.
So the problem is : after entering the correct username and password and pressing the button "Login" (this part works just fine, becouse i'm getting into correct IF section and method returns True) which supposed to call a Main UI window i got nothing happened. After closing manualy the Login window the second Tk()
object (UI window) appears.
My code of Login UI:
class Security:
def __init__(self):
# -------- Window arrangement ------------------- #
self.root = Tk()
self.root.title("Gym Activity Tracker")
self.root.minsize(600, 300)
self.user_name = StringVar()
self.user_pass = StringVar()
# --------- Login labels ---------- #
self.user_label = Label(text="User: ")
self.user_label.grid(column=0, row=1, pady=(20, 5))
self.password_label = Label(text="Password: ", padx=50)
self.password_label.grid(column=0, row=2, pady=(0, 10))
self.info_label = Label(text="(Optional)", anchor="e")
self.info_label.grid(column=2, row=2)
# --------- Login Buttons ---------- #
self.login_button = Button(text="Login", width=25, command=self.security_check)
self.login_button.grid(column=1, row=3)
# --------- Login Entries ---------- #
self.user_name_var = StringVar(self.root)
self.user_name_var.set("Choose an User")
self.user_drop_list = OptionMenu(self.root, self.user_name_var, "sdf")
self.user_drop_list.config(width=24)
self.user_drop_list.grid(column=1, row=1, pady=(20, 5))
self.password_entry = Entry(width=30)
self.password_entry.grid(column=1, row=2)
self.root.mainloop()
def security_check(self):
"""Method validates the user's name and password (if applied) entered
and returns True if security check has been passed"""
user_name_entered = self.user_name_var.get()
user_password_entered = self.password_entry.get()
data = pd.read_csv("settings/users_list.csv")
database_user_pass = data.loc[data.name == f"{user_name_entered}", "password"]
if (f"{user_name_entered}" in data["name"].values) and (str(database_user_pass[1]) == user_password_entered):
return True and self.root.destroy()
elif f"{user_name_entered}" not in data["name"].values:
tkinter.messagebox.showwarning(
title="Username error",
message="User does not exist. Please check a spelling or create a new user"
)
return False
elif str(database_user_pass) == user_password_entered:
tkinter.messagebox.showwarning(
title="Password error",
message="Password is not correct for this user"
)
return False
else:
print("Something went wrong with Security Check")
return False
Which runs from main.py :
from frames.security import Security
from frames.ui import MainInterface
def main():
authorization = Security()
if authorization.security_check():
app = MainInterface()
Functionality of Security/Login window works well. Functionality of Main UI windows works well too.
How to make a programm to close the Security/Login window and run another Toplevel
window? After executing the self.root.destroy()
command in security_check function i get the tkinter error can't invoke "destroy" command: application has been destroyed
CodePudding user response:
I'm not exactly sure on how to fix your issue but instead you could try to use ''' sys.exit(1) ''' after you exit out of the UI
CodePudding user response:
It is not recommended to call mainloop()
inside __init__()
. Create another class method for this.
Also you should return the login status from the above-mentioned class method and don't call security_check()
again as it is already called when Login button is clicked. You should destroy the login window inside security_check()
when the login is successful.
frames/security.py
from tkinter import *
import tkinter.messagebox
import pandas as pd
class Security:
def __init__(self):
# -------- Window arrangement ------------------- #
self.root = Tk()
self.root.title("Gym Activity Tracker")
self.root.minsize(600, 300)
# instance variable for login status
self.login_passed = False
self.user_name = StringVar()
self.user_pass = StringVar()
# --------- Login labels ---------- #
self.user_label = Label(text="User: ")
self.user_label.grid(column=0, row=1, pady=(20, 5))
self.password_label = Label(text="Password: ", padx=50)
self.password_label.grid(column=0, row=2, pady=(0, 10))
self.info_label = Label(text="(Optional)", anchor="e")
self.info_label.grid(column=2, row=2)
# --------- Login Buttons ---------- #
self.login_button = Button(text="Login", width=25, command=self.security_check)
self.login_button.grid(column=1, row=3)
# --------- Login Entries ---------- #
self.user_name_var = StringVar(self.root)
self.user_name_var.set("Choose an User")
self.user_drop_list = OptionMenu(self.root, self.user_name_var, "sdf")
self.user_drop_list.config(width=24)
self.user_drop_list.grid(column=1, row=1, pady=(20, 5))
self.password_entry = Entry(width=30)
self.password_entry.grid(column=1, row=2)
# don't call mainloop() inside __init__()
def run(self):
self.root.mainloop()
return self.login_passed
def security_check(self):
"""Method validates the user's name and password (if applied) entered
and returns True if security check has been passed"""
user_name_entered = self.user_name_var.get()
user_password_entered = self.password_entry.get()
data = pd.read_csv("settings/users_list.csv")
database_user_pass = data.loc[data.name == f"{user_name_entered}", "password"]
if (f"{user_name_entered}" in data["name"].values) and (str(database_user_pass[0]) == user_password_entered):
# set login status to successful
self.login_passed = True
# destroy the login window
self.root.destroy()
return True
elif f"{user_name_entered}" not in data["name"].values:
tkinter.messagebox.showwarning(
title="Username error",
message="User does not exist. Please check a spelling or create a new user"
)
return False
elif str(database_user_pass) != user_password_entered: ####
tkinter.messagebox.showwarning(
title="Password error",
message="Password is not correct for this user"
)
return False
else:
print("Something went wrong with Security Check")
return False
main.py
from frames.security import Security
from frames.ui import MainInterface
def main():
authorization = Security().run()
if authorization:
app = MainInterface()