Excellent! Not only does that work, it may also allow me to throw away several blocks of "if self.doFoo:" code!
That takes take of menu items. But I need this for entire menus too. How would I do the same kind of thing for entire menus on the menubar?
E.g., one of my menubar menus is "Grid." That entire menu should be enabled when one or more grid-containing objects are open, and disabled otherwise. What I currently have to do is this:
self.menuBar.EnableTop(2, self.have_grids)
I'd love to be able to eliminate (a) the menu-position-dependent enabling/disabling, and (b) the non-event-driven line of code itself.
BTW, when I tried binding an update handler to the menu, I got the message
AttributeError: 'Menu' object has no attribute 'GetId'
If this can't be automated, then I won't be able to eliminate those "if self.doFoo:" blocks after all.
Here's hoping!
Bob
···
At 01:01 PM 11/26/2007, Robin Dunn wrote:
Bob Klahn wrote:
I like the approach Robin lays out in Listing 6.4 (pages 159-160) of "wxPython in Action" to create an application's menu bar, menus, and menu items.
But I need to be able to disable or enable specific menu items as various situations arise. Robin's approach does not create separate menu-item id's, so I'm currently at a loss as to how best to accomplish that.In addition to the handler for EVT_MENU you can (optionally) have an entry in the data structure for a handler for EVT_UPDATE_UI for each item, (or at least those that need it.) The EVT_UPDATE_UI handlers are called periodically and is an easy way to enable/disable, check/uncheck, etc. menu, toolbar and other items. The handlers just need to call a method of the event object, and wx takes care of propagating that value to the actual item.
For example, suppose you have a Foo menu item, and you want it to be enabled or disabled based on some doFoo property of the frame class. In that case the EVT_UPDATE_UI handler can be as simple as this:
def OnUpdateUI_Foo(self, evt):
evt.Enable(self.doFoo)