Mike Driscoll ha scritto:
If you already have a menubar, then why isn't this working? You're not using the same id in your menu that you are in your accelerator table are you? I'm not...
Exactly. I'd like to use a wholly new id, apart from those existing in my menus. And I wish I could avoid to insert an hidden menu item solely to make my accelerator table to work.
Maybe my code is confusing, but the id in my menu is different than the one in my accelerator table. First, I create a menu item:
exitMenuItem = fileMenu.Append(wx.NewId(), "Exit", "Exit the application")
Notice the wx.NewId() call. Then I create another id:
exitId = wx.NewId()
and bind it to EVT_MENU, which is what is needed for an accelerator to work:
self.Bind(wx.EVT_MENU, self.onExit, id=exitId )
I forgot to bind my menu item, so here's how I would do that:
self.Bind(wx.EVT_MENU, self.onExit, exitMenuItem)
Notice that both the menu item AND the accelerator table are bound to the same event handler, but have different ids. Can you provide a small runnable sample of the code that's giving you fits so the rest of us can take a look?
Oh, pardon! I didn't notice that... and to be honest I didn't try your code because I supposed that was analogous to what I was trying in my earlier tests...
Now I understand that the way is to have any menu bar set in the frame, even if it isn't useful.
Indeed, I reduced the issue to the fact that, if a menu bar is not present in the frame, one MUST set one as follows:
self.SetMenuBar(wx.MenuBar())
And then any created id can be used and bound to any handler by a wx.AcceleratorTable.
The following code works if the line "self.SetMenuBar(wx.MenuBar())" is uncommented:
<code>
import wx
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "wx.Menu Tutorial")
# Add a panel so it looks the correct on all platforms
self.panel = wx.Panel(self, wx.ID_ANY)
self.SetMenuBar(wx.MenuBar())
exitId = wx.NewId()
self.Bind(wx.EVT_MENU, self.onExit, id=exitId )
accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('Q'), exitId )])
self.SetAcceleratorTable(accel_tbl)
def onExit(self, event):
print 'in onExit'
# Run the program
if __name__ == "__main__":
app = wx.PySimpleApp()
frame = MyForm().Show()
app.MainLoop()
</code>
Anyway, my question remains: Why one _must_ set a menubar in order to make an accelerator table to work ? Maybe the answer is "Because actually an accelerator entry is assumed to be strictly connected to something like a menu item" but I think it should work even without.
Mike
Thanks a lot.