python tkinter open new window with button click and close first window
<p>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 <code>self.destroy()</code> but it close the entire program.</p>

<p>here is the code</p>

<pre><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('&lt;Return&gt;', 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()
</code></pre>

<p>In my opinion, the best solution is to make each of your sections of the GUI (login page, main page) a subclass of <code>Frame</code> rather than <code>Toplevel</code> or <code>Tk</code>. 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.</p>

<p>Anoter way to get the same effect is to make your main window a subclass of <code>Tk</code>, and have your login window be a <code>Toplevel</code>. 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.</p>

python python-3.x user-interface tkinter