0

I'm planning on making a fairly complex GUI in Python using Tkinter for a senior project. I came across this link that provides a great structured way to go about handling switching between frames by stacking them.

I want to make a simple quit button that exits the program when pressed because the GUI I plan to make will not have the window frame around it to minimize, maximize or exit. If I add a function such as this:

def quit_program(self):

    self.destroy()

And I put that function below the show_frame function and then in another class call upon it like so:

button3 = tk.Button(self, text="Quit",
                        command=lambda: controller.quit_program)

It doesn't work. Why is that? And how would I go about making a quit button with this frame structure?

Seth Law
  • 3
  • 1

2 Answers2

2

I have taken your code, and I could see a few errors with it. With some manipulation, I have managed to make it work. This is the result:

import Tkinter as tk
root = tk.Tk()
button3 = tk.Button(text="Quit", command=lambda: quit_program())
def quit_program():
    root.destroy()
button3.pack()
root.mainloop()

Good luck!

Jordan.

----- EDIT -----

Sorry, I failed to read your question fully. Hopefully this will aid your endeavours.

I put Brian's code into a program, and I added the destroy function just as you said. I then added a button in the class StartPage, in the function __init__. It can be found here, with the name button3.

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 page", 
font=controller.title_font)
        label.pack(side="top", fill="x", pady=10)

        button1 = tk.Button(self, text="Go to Page One",
                        command=lambda: 
controller.show_frame("PageOne"))
        button2 = tk.Button(self, text="Go to Page Two",
                        command=lambda: 
controller.show_frame("PageTwo"))
        button3 = tk.Button(self, text="Quit",
                        command=lambda: 
controller.quit_program())
        button1.pack()
        button2.pack()
        button3.pack()

My code ended up working perfectly, where when you press the button, it quits the program. I think you'll find that when you were calling on the quit_program function, you were calling it like: controller.quitprogram, where you should be adding in the parentheses after it, as it is a function, like: controller.quit_program(). I haven't seen what you have actually put into your code, but in your question, you did not include the parentheses in your call.

Hope this helps!

Jordan.

  • thanks for the reply, however it's not quite what I was looking for. I was trying to add a quit button to the code posted in the link. I understand your answer completely, but I was hoping for an answer as to why it wasn't working if I added it to the answer posted by Brain Oakley that I linked in my question. Sorry if I wasn't clear enough in my question, first post on stack overflow! – Seth Law Mar 01 '18 at 01:58
  • 2
    You can dispose of the lambda: replace `command=lambda: controller.quit_program())`, with `command=controller.quit_program)` – Reblochon Masque Mar 01 '18 at 02:34
1
button3 = tk.Button(self, text="Quit",
                        command=lambda: controller.quit_program)

Doesn't make button3 to call anything as it lacks the call () syntax inside lambda. Replace it with:

button3 = tk.Button(self, text="Quit",
                        command=lambda: controller.quit_program())

or better yet with:

button3 = tk.Button(self, text="Quit",
                        command=controller.quit_program)

Additionally, If you want to make quit functionality, you can use quit method instead, as it will destroy all GUI as opposed to the object it's attached to like destroy does:

button3 = tk.Button(self, text="Quit",
                        command=controller.quit)
Nae
  • 14,209
  • 7
  • 52
  • 79