Python 3.4 Tkinter, Understanding code/setting window size
Question: I'm trying to make a tkinter GUI using classes, which I'm pretty new to (I
have watched all of TNB's tutorials on it), and I'm having some issues with
implementing features into my code and understanding it. I'm trying to adapt
code I found on this site to get the basic structure and I can't figure out
how/why some of it works and how to add some things in.

This is my code so far:

    
    
    import tkinter as tk
    
    
    class Application(tk.Tk):  # Inheriting tkinter classes etc.
    
        def __init__(self):
            tk.Tk.__init__(self)  # Creates window?
            container = tk.Frame(self)  # Creates frame object
            container.pack(side="top", fill="both", expand=True)  # Places container/frame inside window
            container.grid_rowconfigure(0, weight=1)  # ?
            container.grid_columnconfigure(0, weight=1)  # ?
    
            self.frames = {}  # What does this do?
            for F in (MenuPage, StartPage, InfoPage, SettingsPage):
                page_name = F.__name__  # What is __name__ for?
                frame = F(container, self)
                self.frames[page_name] = frame  # Creating dictionary entries?
                frame.grid(row=0, column=0, sticky="NSEW")
            self.show_frame("MenuPage")  # Pushes menu page to top when initialised
    
        def show_frame(self, page_name):
            frame = self.frames[page_name]
            frame.tkraise()  # Raises frame to top of stack
    
    
    class MenuPage(tk.Frame):
    
        def __init__(self, parent, controller):
            tk.Frame.__init__(self, parent)
            self.controller = controller
            label = tk.Label(self, text="This is the menu page")
            label.pack(side="top", fill="x", pady=10)
    
            # Begins quiz
            start_btn = tk.Button(self,
                                  text="Start",
                                  command=lambda : controller.show_frame("StartPage"))
            start_btn.pack()
    
            # Takes user to information page
            info_btn = tk.Button(self,
                                 text="Information",
                                 command=lambda: controller.show_frame("InfoPage"))
            info_btn.pack()
    
            # Takes user to settings page
            settings_btn = tk.Button(self,
                                     text="Settings",
                                     command=lambda: controller.show_frame("SettingsPage"))
            settings_btn.pack()
    
            # Quits program/closes all GUIs
            quit_btn = tk.Button(self,
                                 text="Quit",
                                 command=self.controller.destroy)
            quit_btn.pack()
    
    
    # First page of quiz, will need to inherit from settings?
    class StartPage(tk.Frame):
    
        def __init__(self, parent, controller):
            tk.Frame.__init__(self, parent)
            self.controller = controller
            label = tk.Label(self, text="This is the start")
            label.pack(side="top", fill="x", pady=10)
    
    
    class InfoPage(tk.Frame):
    
        def __init__(self, parent, controller):
            tk.Frame.__init__(self, parent)
            self.controller = controller
            label = tk.Label(self, text="This is the info page")
            label.pack(side="top", fill="x", pady=10)
    
            # Takes user back to main menu
            menu_btn = tk.Button(self,
                                 text="Go to the menu page",
                                 command=lambda: controller.show_frame("MenuPage"))
            menu_btn.pack()
    
    
    class SettingsPage(tk.Frame):
    
        def __init__(self, parent, controller):
            tk.Frame.__init__(self, parent)
            self.controller = controller
            label = tk.Label(self, text="This is the settings page")
            label.pack(side="top", fill="x", pady=10)
    
            # Takes user back to main menu
            menu_btn = tk.Button(self,
                                 text="Go to the menu page",
                                 command=lambda: controller.show_frame("MenuPage"))
            menu_btn.pack()
    
    if __name__ == "__main__":  # What does this do?
        app = Application()
        app.mainloop()
    

(I want to add in functionality for the quit button where it actually closes
the whole GUI program. So far I have tried various methods of using .destroy()
as the button command and just the quit command, but I'm having no luck. I
also tried having the destroy function inside the Application() class, and
calling it from the command but that didn't work either. I'm not sure whether
I'm using it right or not.) - Fixed, thanks to Bryan Oakley and furas.

Another thing I have no clue how to do is changing the size parameters of the
windows, so that every window is say (500x200). This is easy when not using
classes, but I don't even know where to begin when using them, and having
multiple frames.

I have also marked/labelled some lines of code that it would be great if
someone could explain to me. There has been a post before going through some
parts of the original code explaining, but they only addressed specific parts
requested by that user.

Thanks in advance :) (Hoping all the indentation has copied over right now)


Answer: This code was designed so that the main program (the "controller") is the
central point for controlling the GUI. That is why `self` (the application
itself) is passed in as the `controller` parameter to the other frames.

Thus, to call any function on the controller from one of the other pages you
would call `self.controller.destroy()`. To associate that with the quit button
you would do it like this:

    
    
    quit_btn = tk.Button(self, text="Quit", command=self.controller.destroy)
    quit_btn.pack()
    

Note: it's a very bad habit to create widgets and lay them out -- calling
`pack` or `grid` or `place` \-- in a single statement. You should always
separate the creation of widgets from arranging them on the screen. When you
do it in a single statement, your variable will always be set to `None`, which
is useless.

