Mobin Taneh Mobin Taneh - 3 months ago 38
Python Question

python tkinter open new window with button click and close first window

I have a login window. I want to close that login window when access is granted to a user, and open a new window. I've searched a lot to find a solution to this simple problem, but didn't understand how to do that. I tried

self.destroy()
but it close the entire program.

here is the code

#!/usr/bin/python

from tkinter import *
from tkinter import ttk


class Login(Tk):
def __init__(self):
super().__init__()
self.uname_var = StringVar()
self.pword_var = StringVar()
self.init_widgets()

def init_widgets(self):
# frame
mainframe = ttk.Frame(self, padding='5 5')
mainframe.grid(row=0, column=0, sticky=(N, E, S, W))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

# label
ttk.Label(mainframe, text='Username').grid(row=0, column=0, sticky=W)
ttk.Label(mainframe, text='Password').grid(row=1, column=0, sticky=W)

# entry
uname_entry = ttk.Entry(mainframe, width=20, textvariable=self.uname_var)
uname_entry.grid(row=0, column=1, sticky=(E, W))
pword_entry = ttk.Entry(mainframe, width=20, textvariable=self.pword_var)
pword_entry.grid(row=1, column=1, sticky=(E, W))

# button
ttk.Button(mainframe, text='Sign in', command=self.check_login).grid(row=2, column=1, sticky=E)

for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)

uname_entry.focus()
self.bind('<Return>', self.check_login)

def check_login(self, *args):
uname = self.uname_var.get()
pword = self.pword_var.get()
if uname == 'admin' and pword == 'admin':
print("Access Granted")
new = MainForm()
new.title("Main Window")
#self.destory()
# HERE I WANT TO CLOSE THIS WINDOW
else:
print("Access Denied")


class MainForm(Toplevel):
def __init__(self):
super().__init__()
self.init_widgets()

def init_widgets(self):
mainframe = ttk.Frame(self, padding='5 5')
mainframe.grid(column=0, row=0, sticky=(N, E, S, W))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
ttk.Button(mainframe, text='Click me').grid(column=0, row=0, sticky=(N, W))


def main():
root = Login()
root.title("Login")
root.mainloop()

if __name__ == '__main__': main()

Answer

In my opinion, the best solution is to make each of your sections of the GUI (login page, main page) a subclass of Frame rather than Toplevel or Tk. With that, you can simply destroy the frame representing the login frame, and replace it with the frame representing the main part of your application. This way you don't have to destroy any windows.

Anoter way to get the same effect is to make your main window a subclass of Tk, and have your login window be a Toplevel. At startup you can hide the root window and show the login window, and then when the user logs in you can hide or destroy the login window and show the root window.