Why isn’t EVT_CLOSE fired when I click the OK or Cancel buttons in a wx.Dialog?
wxpython, wxwidgets
Solution
When you click the Ok or Cancel buttons on a modal dialog the dialog is not closed with `Close`, instead it is ended with `EndModal` so the `EVT_CLOSE` event is not sent. Code that needs to run when a modal dialog is completed normally is usually put after the call to `ShowModal`. I think in this case that the documentation is incorrect.
OTOH, if the dialog is shown modeless (with `Show` instead of `ShowModal`) then they should be closed with `Close` and you will get the `EVT_CLOSE` event.
Problem
I have a wx.Dialog subclass that needs to perform a couple of cleanup operations when the user clicks the OK button. The wx.Dialog documentation says that clicking OK or Cancel should emit an EVT_CLOSE event: EVT_CLOSE: The dialog is being closed by the user or programmatically (see Window.Close ). The user may generate this event clicking the close button (typically the ‘X’ on the top-right of the title bar) if it’s present (see the CLOSE_BOX style) or by clicking a button with the ID_CANCEL or ID_OK ids. I’m using WX 2.9.5.0 (via wxPython), however, and when I click OK or Cancel in this test application the OnClose method is not called. OnClose is called when I click the system’s close button (I’m using OS X). Am I implementing this event-handling wrong or does wx.Dialog really not conform to its documentation? And in the latter case, what’s the best way to intercept a click on the OK button? ``` from __future__ import print_function import wx class TestDialog(wx.Dialog): def __init__(self, parent): wx.Dialog.__init__(self, parent, title='Test Dialog') sizer = wx.BoxSizer(wx.VERTICAL) message = wx.StaticText(self, wx.NewId(), 'This is some dummy text') sizer.Add(message) ok_button = wx.Button(self, wx.ID_OK, 'OK') cancel_button = wx.Button(self, wx.ID_CANCEL, 'Cancel') btn_sizer = self.CreateStdDialogButtonSizer(wx.OK | wx.CANCEL) btn_sizer.Add(cancel_button) btn_sizer.Add(ok_button) sizer.Add(btn_sizer) self.SetSizer(sizer) self.Bind(wx.EVT_CLOSE, self.OnClose) def OnClose(self, event): print('In OnClose') event.Skip() if __name__ == '__main__': app = wx.App(False) dialog = TestDialog(None) result = dialog.ShowModal() print('Result: {}'.format(result)) ```