1

For my current project with tkinter I was in the need of having multiple pages in my GUI and was able to achieve this through the answer I have linked to here Switch between two frames in tkinter.

However, I can't find a way to implement a call to a root window without ruining this preexisting code. I am trying to create a widget button to destroy the root window but I can't locate the specific root to destroy.

from tkinter import *

class MainApp(Tk):
    """Class that displays respective frame"""
    def __init__(self):
        Tk.__init__(self)
        self.winfo_toplevel().title("YouTube Ripper and Editor")
        self.resizable(0, 0)
        container = Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (StartPage, Downloader, Audio_Player, Config, About):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame
            frame.grid(row=0, column=0, sticky="NSEW")

        self.show_frame("StartPage")

    def show_frame(self, page_name):
        """Raise called frame"""
        frame = self.frames[page_name]
        frame.tkraise()


class StartPage(Frame):
    """Class that contains the start page"""
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        self.configure(bg = f_color)
        self.controller = controller
        b_font = Font(family = "Franklin Gothic Book", size = 12)

        titleLabel = Label(self, text="Youtube Ripper and Editor", font = ("Franklin Gothic Book", 16,  "bold"), bg = f_color)
        titleLabel.pack(side="top", fill="x", pady= 30)

        button1 = Button(self, text="Downloader", command=lambda: controller.show_frame("Downloader"),
                            font = b_font, bg = b_color, activebackground = bp_color)
        button2 = Button(self, text="Audio Player", command=lambda: controller.show_frame("Audio_Player"),
                            font = b_font, bg = b_color, activebackground = bp_color)
        button3 = Button(self, text="MP3 Configurator", command=lambda: controller.show_frame("Config"),
                            font = b_font, bg = b_color, activebackground = bp_color)
        button4 = Button(self, text="About", command=lambda: controller.show_frame("About"),
                            font = b_font, bg = b_color, activebackground = bp_color)
        button5 = Button(self, text="Exit", command=self.exit, font = b_font, bg = b_color, activebackground = bp_color)
        # button1.pack(fill = 'x')
        # button2.pack(fill = 'x')
        # button3.pack(fill = 'x')
        # button4.pack(fill = 'x')
        button5.pack(fill = 'x')


    def exit(self):
        """Exit program"""
        MainApp.destroy()


def main():
    app = MainApp()
    app.mainloop()


main()
martineau
  • 119,623
  • 25
  • 170
  • 301
MoonRider
  • 37
  • 1
  • 8
  • The root windows is the `app` instance of `MainApp` — which unfortunately is a local variable in the `main()` function. However, inside the methods of the `MainApp` class, it's `self`. Where are you trying to create this `Button`? – martineau Jan 07 '20 at 00:06
  • I'm trying to create the 'Exit' button in the StartPage class init (button5). – MoonRider Jan 07 '20 at 00:11
  • Then I think @Junuxx answer will work. – martineau Jan 07 '20 at 00:13

1 Answers1

2

Use the reference to the root window that you have saved in StartPage's __init__, and call destroy on that

def exit(self):
    """Exit program"""
    self.controller.destroy()
martineau
  • 119,623
  • 25
  • 170
  • 301
Junuxx
  • 14,011
  • 5
  • 41
  • 71
  • 1
    Technically speaking, there's no guarantee that the controller of a page is a root window. It is in this specific case but there's nothing in the definition of `StartPage` that requires it to be so. – Bryan Oakley Jan 07 '20 at 01:00
  • @BryanOakley: Absolutely. I would use a different structure myself, but I'm not going to recommend a full refactor when a single line will fix the immediate issue. – Junuxx Jan 07 '20 at 01:12
  • As for my project, works great. Thank you for the help! – MoonRider Jan 07 '20 at 03:40