Search code examples
wxpythonwxwidgets

Using Command-W or Control-W to close a Frame


I have a wx.Frame subclass that the user should be able to close by pressing Command-W (on OS X) or Control-W (on Windows). My code looks like

def MyWindow(wx.Frame):
    def __init__(self):
        # ...
        self.Bind(wx.EVT_KEY_DOWN, self.handle_key)
        # ...

    def handle_key(self, event):
        if event.GetKeyCode() == wx.WXK_CONTROL_W:
            self.Destroy()

Under Windows, handle_key does nothing until I have focused the Frame by clicking in it. After that, pressing a key triggers handle_key, but the Ctrl and W trigger separate invocations of the function so the conditional is never satisfied.

Under OS X, handle_key is never called for any keypress, not even after I click within the Frame to set focus.

How can I implement this keypress handler so that

  1. Its behavior is consistent across platforms, except for Ctrl vs. Cmd, and
  2. the user can press the key combination at any time while the Frame is frontmost, regardless of which window actually has focus?

Solution

  • You should use an AcceleratorTable instead of trying to catch the keypresses yourself. Here's a link to the docs:

    You may find this tutorial helpful too:

    In your case, the code would look something like this:

    exitId = wx.NewId()
    self.Bind(wx.EVT_MENU, self.onExit, id=exitId )
    
    accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('W'), exitMenuItem.GetId()) ])
    self.frame.SetAcceleratorTable(accel_tbl)