How to handle a main window button using closing event (Tkinter X button)?
here is how I would edit the code:
from tkinter import *
class win1:
def __init__(self, master):
self.master = master
self.master.geometry('200x100+0+0')
self.btn1 = Button(self.master, text='Click', command=self.openwin)
self.btn1.pack()
def openwin(self):
self.openwin2 = Toplevel(self.master)
app = win2(self.openwin2, self)
self.btn1['state'] = 'disabled'
class win2:
def __init__(self, master, main_window):
self.master = master
self.main_window = main_window
self.master.geometry('200x100+100+100')
self.btn1 = Label(self.master, text='Click the close button')
self.btn1.pack()
self.master.protocol("WM_DELETE_WINDOW", self.closewin)
def closewin(self):
self.main_window.btn1['state'] = 'normal'
self.master.destroy()
def main():
root = Tk()
app = win1(root)
root.mainloop()
if __name__ == '__main__':
main()
the parts I changed:
def closewin(self):
self.main_window.btn1['state'] = 'normal'
self.master.destroy()
and this:
class win2:
def __init__(self, master, main_window):
self.master = master
self.main_window = main_window
and this:
def openwin(self):
self.openwin2 = Toplevel(self.master)
app = win2(self.openwin2, self)
self.btn1['state'] = 'disabled'
also I would suggest using those classes differently but You do You (does not seem too bad)
tkinter - undock frame and handle window close event
Why is the type of self.dockable_frame a <class 'tkinter.Frame'> and not a TopLevel since the wm manage documentation says: The widget specified will become a stand alone top-level window?
I think it is because self.dockable_frame
is a python class and doesn't know that the underlying widget has been changed. Arguably this is a bug in wm_manage
.
How can I handle the window close event since self.dockable_frame.protocol("WM_DELETE_WINDOW", insert_function_here) gives an error on my Windows PC?
The simplest way is to call the method directly from the tk.Wm
class. It would look like this:
tk.Wm.protocol(self.dockable_frame, "WM_DELETE_WINDOW", self.whatever)
Overriding Tkinter X button control (the button that close the window)
It sounds as if your save window should be modal.
If this is a basic save window, why are you reinventing the wheel?Tk
has a tkFileDialog
for this purpose.
If what you want is to override the default behaviour of destroying the window, you can simply do:
root.protocol('WM_DELETE_WINDOW', doSomething) # root is your root window
def doSomething():
# check if saving
# if not:
root.destroy()
This way, you can intercept the destroy()
call when someone closes the window (by any means) and do what you like.
Execute a certain command before closing window in tkinter
Depending on what you want to do when the window closes, a possible solution is to wrap your GUI into a class, initialize it in a with
statement and do your work in the __exit__()
method:
import tkinter
class MainWindow(object):
def __init__(self):
print("initiated ..")
self.root = tkinter.Tk()
def __enter__(self):
print("entered ..")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Main Window is closing, call any function you'd like here!")
with MainWindow() as w:
w.root.mainloop()
print("end of script ..")
the window close event, not run in a window without the window manager?
The WM_DELETE_WINDOW protocol and other protocols are specifically related to window manager protocols. If you don't have a window manager, they don't apply.
From the protocol man page:
This command is used to manage window manager protocols...
In the absence of a window manager, you can bind to the <Destroy>
event which should fire whether you have a window manager or not. You have to be careful with this if you bind to the root window. Bindings on the root widget or a Toplevel
will apply to all descendant widgets, so in the bound function you'll want to run code only if event.widget
refers to the root or Toplevel
window.
Detect when the x or close button is pressed
You can override the closing protocol.
def on_close():
#custom close options, here's one example:
close = messagebox.askokcancel("Close", "Would you like to close the program?")
if close:
root.destroy()
root.protocol("WM_DELETE_WINDOW", on_close)
Related Topics
Catch a Thread's Exception in the Caller Thread
How to Use a Python Script in the Command Line Without Cd-Ing to Its Directory? Is It the Pythonpath
Change the Name of a Key in Dictionary
Set Matplotlib Colorbar Size to Match Graph
Writing Unicode Text to a Text File
Using Os.Walk() to Recursively Traverse Directories in Python
Quoting Backslashes in Python String Literals
Typeerror: Can't Convert 'Int' Object to Str Implicitly
Convert Excel Style Date with Pandas
Multiprocessing.Pool: When to Use Apply, Apply_Async or Map
Convert Integer to String in Python
How to Create a Custom String Representation for a Class Object
How to Display Pandas Dataframe of Floats Using a Format String for Columns
Count Number of Occurrences of a Substring in a String