3

I am building a GUI application using Python and Tkinter. I want to control the behavior of the program when the user closes it.

I've installed a new WM_DELETE_WINDOW protocol using:

root = Tk()
root.protocol("WM_DELETE_WINDOW", lambda: closes_gracefully())

This indeed is working when the user clicks the X button on the titlebar, but it is NOT working when the user presses ALT+F4.

I tried binding the key sequence: root.bind("<Alt-F4>", lambda: closes_gracefully()) but it did not work.

How can I capture the ALT+F4 event?

Melebius
  • 6,183
  • 4
  • 39
  • 52
NirMH
  • 4,769
  • 3
  • 44
  • 69
  • `lambda: closes_gracefully()` is just `closes_gracefully`, by the way. – TigerhawkT3 Jan 24 '17 at 08:28
  • 3
    Just tried in my app and this works well for me: `self.bind('', self.whatever_your_want)` – CommonSense Jan 24 '17 at 08:29
  • Related: http://stackoverflow.com/questions/30157521/unclosable-window-using-tkinter – TigerhawkT3 Jan 24 '17 at 08:30
  • @CommonSense: thanks - my issue was with the binding statement - should be `` – NirMH Jan 24 '17 at 08:33
  • 2
    Your current code works fine for me. Please add a [mcve]. – TigerhawkT3 Jan 24 '17 at 08:34
  • 1
    Just a note: Alt+F4 is platform dependent, for example Macs use Cmd+Q / Cmd+W. – Melebius Jan 24 '17 at 09:41
  • @Melebius, they arent the same, try them in chrome, they close the entire application/active tab respectively, rather than the active window as Alt-F4 does – Nick is tired Aug 26 '17 at 21:40
  • @NickA Yes, that’s their correct behavior. I just wanted to point out that they are used _instead_ of Alt+F4 on Macs. (There is also Shift+Cmd+W shortcut used to close a window containing tabs as you mentioned.) Therefore I would prefer a platform independent solution instead of hardcoded binding of Alt+F4. – Melebius Aug 27 '17 at 05:34

1 Answers1

3

For this purpose, you could use atexit.register.

It works like a stack that is executed when the program gets closed. Every time you do register(function), this function gets pushed on top. If you added a, b and c they get executed in the opposite order(c, b, a).

In your case, you should do:

register(closes_gracefully)

You should note that this works almost always, except with crashes(alt-f4 works too, just tested it).

You can even use register as a decorator when the function takes no parameters:

@register
def bye():
    print("I'm out!")
Zachary Espiritu
  • 937
  • 7
  • 23
r0w
  • 155
  • 1
  • 13