Reputation: 164
I have a main tkinter window which launches multiple pop up windows. I am trying to close all windows by pressing the cross in the pop up window or by pressing quit. I have the following code which closes only the pop up window by pressing the quit or cross, but does not close the main window.How to refactor the code to achieve the desired output.
import tkinter as tk
from tkinter import *
class myclass:
def __init__(self,master):
self.master = master
self.button = tk.Button(self.master, text = "Function", command = self.launchFunc)
self.button.place(width=160,height=50, x=20, y=20)
self.quit = tk.Button(self.master, text = "Quit", command = self.close_windows)
self.quit.place(width=160,height=50, x=20, y=80)
def close_windows(self):
self.master.destroy()
def launchFunc(self):
self.top = tk.Toplevel(self.master)
self.top.transient(self.master)
self.app = funcClass(self.top)
class funcClass:
def __init__(self, master):
self.master1 = master
self.quit = tk.Button(self.master1, text = "Quit", command = self.close_windows)
self.quit.place(width=160,height=50, x=20, y=20)
def close_windows(self):
self.a = myclass(self.master1)
self.a.close_windows()
if __name__ == "__main__":
root = tk.Tk()
myclass = myclass(root)
root.mainloop()
Please guide me. Thank you
Upvotes: 1
Views: 866
Reputation: 47163
You need to register a callback function which will be executed when the X
button on the title bar is clicked using protocol()
function. You can use the same function for the Quit
button. Then close the root
window inside the callback function:
class funcClass:
def __init__(self, master):
self.master1 = master
self.quit = tk.Button(self.master1, text="Quit", command=self.close_windows)
self.quit.place(width=160, height=50, x=20, y=20)
# for 'X' button in title bar
master.protocol('WM_DELETE_WINDOW', self.close_windows)
def close_windows(self):
# self.master1 is the toplevel
# so self.master1.master is the root window
self.master1.master.destroy()
Upvotes: 1
Reputation: 484
I would recommend making your own popups using simpledialog.Dialog as a base class that you can pass special instructions like this to.
It needs to extend the base class and run the super().init with the parent and title arguments passed so that it will build the popup properly.
class MyPopup(simpledialog.Dialog):
def __init__(self, parent, title, superClose)
self.superClose = superClose
super().__init__(parent, title)
I added the 'superClose' argument to save that for later. Then, we override the destroy method of that class to run that passed argument.
def destroy(self):
super().destroy()
self.superClose()
The super().destroy() will run the the original version of the destroy method and then we run that saved argument we passed earlier.
Make some function that closes things:
def closeOthers():
<go through all your popups you want closed and close them>
And then to make the popup appear:
MyPopup(root, "Title", closeOthers)
When that one is destroyed, it will also call that function.
To customize that popup, overwrite the body method. (you don't need to run super().body()) This is where you should add all your tkinter widgets for the popup.
A couple other things to know: These will have a frame near the bottom that gives you an OK and Cancel button by default, that call ok() and cancel() (which you can override to choose what they do) and binds Enter and Escape to those functions as well. If you don't want this, or what this changed, overwrite the buttonbox method. The cancel function also calls the destroy method, which will run your superClose method too. If you want the cancel button (and escape key) to just close itself and not run superClose, overwrite it with this:
def cancel(self, event=None):
if self.parent is not None:
self.parent.focus_set()
self.initial_focus = None
Toplevel.destroy(self)
If you are okay with how all closing runs the superClose, you could also overwrite apply(self) instead. That will make everything in there run after the popup is destroyed, every time.
def apply(self):
self.superClose()
It also doesn't need a super() call.
I hope that helps. Let us know if you have more questions etc.
Upvotes: 1