I am gettin' stared wiith python. I got a udemy course and also read this post: How To Let Your Main Window Appear after succesful login in Tkinter(PYTHON 3.6
Still, I am unable to implement the recired event. I want to open a new (main) window of the desctop app after login. For some reason the script also opens a third window all of a sudden. I am getting really frusted working since 2 das on that stuff...
Thanks for help:)
from tkinter import Tk, Label, Button, messagebox
from tkinter import *
class AirsoftGunRack:
##### Main Window #####
##### Login Page #####
def __init__(self,master):
"""
:type master: object
"""
##### Login Page #####
self.master = master
master.title("Login - Airsoft GunRack 3.0")
master.geometry("450x230+450+170")
# Creating describtions
self.username = Label(master, text="Username:")
self.username.place(relx=0.285, rely=0.298, height=20, width=55)
self.password = Label(master, text="Password:")
self.password.place(relx=0.285, rely=0.468, height=20, width=55)
# Creating Buttons
self.login_button = Button(master, text="Login")
self.login_button.place(relx=0.440, rely=0.638, height=30, width=60)
self.login_button.configure(command=self.login_user)
self.exit_button = Button(master, text="Exit") # , command=master.quit)
self.exit_button.place(relx=0.614, rely=0.638, height=30, width=60)
self.exit_button.configure(command=self.exit_login)
# Creating entry boxes
self.username_box = Entry(master)
self.username_box.place(relx=0.440, rely=0.298, height=20, relwidth=0.35)
self.password_box = Entry(master)
self.password_box.place(relx=0.440, rely=0.468, height=20, relwidth=0.35)
self.password_box.configure(show="*")
self.password_box.configure(background="white")
# Creating checkbox
self.var = IntVar()
self.show_password = Checkbutton(master)
self.show_password.place(relx=0.285, rely=0.650, relheight=0.100, relwidth=0.125)
self.show_password.configure(justify='left')
self.show_password.configure(text='''Show''')
self.show_password.configure(variable=self.var, command=self.cb)
def cb(self, ):
if self.var.get() == True:
self.password_box.configure(show="")
else:
self.password_box.configure(show="*")
# Giving function to login process
def login_user(self):
name = self.username_box.get()
password = self.password_box.get()
if name == "user" and password == "1234":
self.main_win.deiconify() #Unhides the root window
self.master.destroy() #Removes the toplevel window
#messagebox.showinfo("Login page", "Login successful!")
else:
messagebox.showwarning("Login failed", "Username or password incorrect!")
def exit_login(self):
msg = messagebox.askyesno("Exit login page", "Do you really want to exit?")
if (msg):
exit()
main_win = Toplevel()
main_win.title("Main Window")
main_win.title("Main Window")
main_win.geometry("800x800+450+170")
root = Tk()
gunrack = AirsoftGunRack(root)
root.mainloop()
#main_win.withdraw()
main_win.mainloop()
The moment you create a new instance of root = Tk() you will automatically get a small default window opened.
1st) You have root = Tk()
2nd) You have the initialized master
3rd) You have the main_win
Therefore you have three windows
You have to avoid to call the class Tk() again outside of the class and that is the annoying 3rd window problem.
What i would suggest to do is to add a def that it will only mainloop your AirsoftGunRack window.
Here is the final code:
from tkinter import Tk, Label, Button, messagebox
from tkinter import *
class AirsoftGunRack:
def __init__(self,master = Tk()): #This is my first change so i already initialize a Tk window inside the class
"""
:type master: object
"""
##### Login Page #####
self.master = master
master.title("Login - Airsoft GunRack 3.0")
master.geometry("450x230+450+170")
# Creating describtions
self.username = Label(master, text="Username:")
self.username.place(relx=0.285, rely=0.298, height=20, width=55)
self.password = Label(master, text="Password:")
self.password.place(relx=0.285, rely=0.468, height=20, width=55)
# Creating Buttons
self.login_button = Button(master, text="Login")
self.login_button.place(relx=0.440, rely=0.638, height=30, width=60)
self.login_button.configure(command=self.login_user)
self.exit_button = Button(master, text="Exit") # , command=master.quit)
self.exit_button.place(relx=0.614, rely=0.638, height=30, width=60)
self.exit_button.configure(command=self.exit_login)
# Creating entry boxes
self.username_box = Entry(master)
self.username_box.place(relx=0.440, rely=0.298, height=20, relwidth=0.35)
self.password_box = Entry(master)
self.password_box.place(relx=0.440, rely=0.468, height=20, relwidth=0.35)
self.password_box.configure(show="*")
self.password_box.configure(background="white")
# Creating checkbox
self.var = IntVar()
self.show_password = Checkbutton(master)
self.show_password.place(relx=0.285, rely=0.650, relheight=0.100, relwidth=0.125)
self.show_password.configure(justify='left')
self.show_password.configure(text='''Show''')
self.show_password.configure(variable=self.var, command=self.cb)
def cb(self, ):
if self.var.get() == True:
self.password_box.configure(show="")
else:
self.password_box.configure(show="*")
# Giving function to login process
def login_user(self):
name = self.username_box.get()
password = self.password_box.get()
if name == "user" and password == "1234":
self.main_win.deiconify() #Unhides the root window
self.master.destroy() #Removes the toplevel window
#messagebox.showinfo("Login page", "Login successful!")
else:
messagebox.showwarning("Login failed", "Username or password incorrect!")
def exit_login(self):
msg = messagebox.askyesno("Exit login page", "Do you really want to exit?")
if (msg):
exit()
def mainloop_window(self): #This is the class function that helps me to mainloop the window
self.master.mainloop()
main_win = Toplevel()
main_win.title("Main Window")
main_win.title("Main Window")
main_win.geometry("800x800+450+170")
gunrack = AirsoftGunRack() # I dont need to pass the root now since its initialized inside the class
gunrack.mainloop_window() # Just mainlooping the authentication window
#main_win.withdraw()
main_win.mainloop()
Notice that i added four comments to this code. In lines 6,82,93,94
This changes will open the windows you worked on.
Those are of course my only changes in your code block.
Please comment this answer if it affects your performance in the tkinter project.
Yes, @Jim Erginbash. That's pretty much how I want it to work, So. I created a seperate class for main win. I thought about the authentification procedure, My idea is to create a new variable( login_completed) with the value "true". if login was successful. In the second step the class main_win shall check if that value is on "true" before unhiding the main window (withdraw command), Sadly. I cant get it work right. Don't know where to add the code and how.
This is the new code so far. I have also renamed some parameters for better understanding, whih window they belong too.
I also noticed, that by closing the login page with the frame button (X) it will also proceed with the code creating the main window. Do you know how to kill it?
from tkinter import Tk, Label, Button, messagebox from tkinter import *
##### Login Page #####
class Login_Page:
def __init__(self,login = Tk()): #This is my first change so i already initialize a Tk window inside the class
"""
:type login: object
"""
self.login = login
login.title("Login - Airsoft GunRack 3.0")
login.geometry("450x230+450+170")
# Creating describtions
self.username = Label(login, text="Username:")
self.username.place(relx=0.285, rely=0.298, height=20, width=55)
self.password = Label(login, text="Password:")
self.password.place(relx=0.285, rely=0.468, height=20, width=55)
# Creating Buttons
self.login_button = Button(login, text="Login")
self.login_button.place(relx=0.440, rely=0.638, height=30, width=60)
self.login_button.configure(command=self.login_user)
self.login_completed = IntVar()
self.exit_button = Button(login, text="Exit") # , command=master.quit)
self.exit_button.place(relx=0.614, rely=0.638, height=30, width=60)
self.exit_button.configure(command=self.exit_login)
# Creating entry boxes
self.username_box = Entry(login)
self.username_box.place(relx=0.440, rely=0.298, height=20, relwidth=0.35)
self.password_box = Entry(login)
self.password_box.place(relx=0.440, rely=0.468, height=20, relwidth=0.35)
self.password_box.configure(show="*")
self.password_box.configure(background="white")
# Creating checkbox
self.var = IntVar()
self.show_password = Checkbutton(login)
self.show_password.place(relx=0.285, rely=0.650, relheight=0.100, relwidth=0.125)
self.show_password.configure(justify='left')
self.show_password.configure(text='''Show''')
self.show_password.configure(variable=self.var, command=self.cb)
def cb(self, ):
if self.var.get() == True:
self.password_box.configure(show="")
else:
self.password_box.configure(show="*")
# Giving function to login process
def login_user(self):
name = self.username_box.get()
password = self.password_box.get()
login_completed = self.login_completed.get()
if name == "user" and password == "1234":
#messagebox.showinfo("Login page", "Login successful!")
self.login.destroy() #Removes the toplevel window
#self.main_win.deiconify() #Unhides the root window
self.login_completed == 1
else:
messagebox.showwarning("Login Failed - Acess Denied", "Username or Password incorrect!")
#return
def exit_login(self):
msg = messagebox.askyesno("Exit login page", "Do you really want to exit?")
if (msg):
exit()
def mainloop_window(self): #This is the class function that helps me to mainloop the window
self.login.mainloop()
login_page = Login_Page() # I dont need to pass the root now since its initialized inside the class
login_page.mainloop_window() # Just mainlooping the authentication window
##### Main Window #####
class Main_Win:
def __init__(self,main_win = Tk()): #This is my first change so i already initialize a Tk window inside the class
"""
:type main_win: object
"""
#main_win.withdraw()
#self.main_win.deiconify() #Unhides the root window
self.main_win = main_win
main_win.title("Airsoft GunRack 3.0")
main_win.geometry("900x500+250+130")
def mainloop_window(self): #This is the class function that helps me to mainloop the window
self.main_win.mainloop()
main_win = Main_Win() # I dont need to pass the root now since its initialized inside the class
main_win.mainloop_window() # Just mainlooping the authentication window
The idea of your authentication is good.
In more advanced levels, you need to start managing your tkinter application with a database ( i suggest postgresql) and manage your users and passwords from there
In order to prevent the bug with the X button, you can add in the class initialization the following line:
login.protocol("WM_DELETE_WINDOW",self.event_X)
Also add this function in the Login class: (define the event_X function)
def event_X(self):
if messagebox.askokcancel("Exit", "Are you sure you want to exit?"):
exit()
This will be the final code:
from tkinter import Tk, Label, Button, messagebox
from tkinter import *
##### Login Page #####
class Login_Page:
def __init__(self, login=Tk()): # This is my first change so i already initialize a Tk window inside the class
"""
:type login: object
"""
self.login = login
login.protocol("WM_DELETE_WINDOW",self.event_X)
login.title("Login - Airsoft GunRack 3.0")
login.geometry("450x230+450+170")
# Creating describtioneves
self.username = Label(login, text="Username:")
self.username.place(relx=0.285, rely=0.298, height=20, width=55)
self.password = Label(login, text="Password:")
self.password.place(relx=0.285, rely=0.468, height=20, width=55)
# Creating Buttons
self.login_button = Button(login, text="Login")
self.login_button.place(relx=0.440, rely=0.638, height=30, width=60)
self.login_button.configure(command=self.login_user)
self.login_completed = IntVar()
self.exit_button = Button(login, text="Exit") # , command=master.quit)
self.exit_button.place(relx=0.614, rely=0.638, height=30, width=60)
self.exit_button.configure(command=self.exit_login)
# Creating entry boxes
self.username_box = Entry(login)
self.username_box.place(relx=0.440, rely=0.298, height=20, relwidth=0.35)
self.password_box = Entry(login)
self.password_box.place(relx=0.440, rely=0.468, height=20, relwidth=0.35)
self.password_box.configure(show="*")
self.password_box.configure(background="white")
# Creating checkbox
self.var = IntVar()
self.show_password = Checkbutton(login)
self.show_password.place(relx=0.285, rely=0.650, relheight=0.100, relwidth=0.125)
self.show_password.configure(justify='left')
self.show_password.configure(text='''Show''')
self.show_password.configure(variable=self.var, command=self.cb)
def event_X(self):
if messagebox.askokcancel("Exit", "Are you sure you want to exit?"):
exit()
def cb(self, ):
if self.var.get() == True:
self.password_box.configure(show="")
else:
self.password_box.configure(show="*")
# Giving function to login process
def login_user(self):
name = self.username_box.get()
password = self.password_box.get()
login_completed = self.login_completed.get()
if name == "user" and password == "1234":
# messagebox.showinfo("Login page", "Login successful!")
self.login.destroy() # Removes the toplevel window
# self.main_win.deiconify() #Unhides the root window
self.login_completed == 1
else:
messagebox.showwarning("Login Failed - Acess Denied", "Username or Password incorrect!")
# return
def exit_login(self):
msg = messagebox.askyesno("Exit login page", "Do you really want to exit?")
if (msg):
exit()
def mainloop_window(self): # This is the class function that helps me to mainloop the window
self.login.mainloop()
login_page = Login_Page() # I dont need to pass the root now since its initialized inside the class
login_page.mainloop_window() # Just mainlooping the authentication window
##### Main Window #####
class Main_Win:
def __init__(self, main_win=Tk()): # This is my first change so i already initialize a Tk window inside the class
self.main_win = main_win
main_win.title("Airsoft GunRack 3.0")
main_win.geometry("900x500+250+130")
def mainloop_window(self): # This is the class function that helps me to mainloop the window
self.main_win.mainloop()
main_win = Main_Win() # I dont need to pass the root now since its initialized inside the class
main_win.mainloop_window() # Just mainlooping the authentication window
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.