If I want to dynamically enable and disable menu items (and toolbar buttons), does this mean I have to create the MenuBar as a top-level XRC node, or can it still be a child of the Frame? If the latter, then how do I access the menu items? I tried to do:
self.menubar = xrc.XRCCTRL(self.frame, 'menuBar')
but I suspect this doesn't work because menus are just different than regular controls.
Furthermore, since corresponding menu items and toolbar buttons have the same IDs (for the same functionality), does this change anything or can I still just get a reference to one thing and then use it to affect both widgets? i.e.:
Hopefully something like this line will get a reference to both the "New Database" menu item as well as the corresponding toolbar button, and then I can enable and disable both at once.
If I want to dynamically enable and disable menu items (and toolbar buttons), does this mean I have to create the MenuBar as a top-level XRC node, or can it still be a child of the Frame? If the latter, then how do I access the menu items? I tried to do:
self.menubar = xrc.XRCCTRL(self.frame, 'menuBar')
but I suspect this doesn't work because menus are just different than regular controls.
use
self.menubar = self.frame.GetMenuBar()
Furthermore, since corresponding menu items and toolbar buttons have the same IDs (for the same functionality), does this change anything or can I still just get a reference to one thing and then use it to affect both widgets? i.e.:
Hopefully something like this line will get a reference to both the "New Database" menu item as well as the corresponding toolbar button, and then I can enable and disable both at once.
Take a look at EVT_UPDATE_UI events for doing things like that.
···
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!
Take a look at EVT_UPDATE_UI events for doing things like that.
This looks like exactly what I need, but I don't understand how to use it. Do I still need to get references to all the individual items I want to enable/disable?
It seems like I do something like this:
self.frame.Bind(EVT_UPDATE_UI, self.UpdateUI)
def UpdateUI(self, event): #what goes here? a bunch of if tests using each control?
Also, in terms of the Bind call (assuming that's even correct), when does EVT_UPDATE_UI get called? Is it called once (or repeatedly?) every time the application goes idle?
This looks like exactly what I need, but I don't understand how to use it. Do I still need to get references to all the individual items I want to enable/disable?
Another issue seems to be that you need the IDs of the widgets, so it does seem necessary to do some extra work to this end if you are using XRC, right? You first have to get references to the widgets, then get those IDs again for the event?
Take a look at EVT_UPDATE_UI events for doing things like that.
This looks like exactly what I need, but I don't understand how to use it. Do I still need to get references to all the individual items I want to enable/disable?
def UpdateUI(self, event): #what goes here? a bunch of if tests using each control?
No, just one. You'll have one of these handlers for every item, and in each you can do something like:
event.Enable(not someCondition)
Also, in terms of the Bind call (assuming that's even correct), when does EVT_UPDATE_UI get called? Is it called once (or repeatedly?) every time the application goes idle?
It depends. By default it's in idle time, but you can adjust that with some static methods of the wx.UpdateUiEvent.
···
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!
def UpdateUI(self, event): #what goes here? a bunch of if tests using each control?
No, just one. You'll have one of these handlers for every item, and in each you can do something like:
event.Enable(not someCondition)
Oh, interesting. So when I write the Bind calls, I have to create a new handler for each one that is tied to the specified control, and in that handler I do the testing to enable/disable it?
That much makes sense, I think. I'll give it a try. But as far as actually calling Enable and Disable, I do this through the event parameter, not through a reference to the controls?
That seems a little odd, I guess because I don't have a good understanding of what 'event' really represents. I figured it had information about the event, but I didn't know you could use it to affect the object itself.
def UpdateUI(self, event): #what goes here? a bunch of if tests using each control?
No, just one. You'll have one of these handlers for every item, and in each you can do something like:
event.Enable(not someCondition)
Oh, interesting. So when I write the Bind calls, I have to create a new handler for each one that is tied to the specified control, and in that handler I do the testing to enable/disable it?
Almost. The update events are designed to be bound per ID, so if you have a menu item and a toolbar item that have the same ID, their update can be controlled by a single update handler.
That much makes sense, I think. I'll give it a try. But as far as actually calling Enable and Disable, I do this through the event parameter, not through a reference to the controls?
Because of the above, you may not know in the handler if you are being called for the menu item, a toolbar item, or a control, etc. so you set the enabled, checked, shown, or label state in the event, and then when control returns to the sender of the event it sorts out what to do based on what kind of item it was sending the event for.
That seems a little odd, I guess because I don't have a good understanding of what 'event' really represents. I figured it had information about the event, but I didn't know you could use it to affect the object itself.
It depends on the type of event. For example, some kinds of events are able to be vetoed, or need to be explicitly allowed by the handler, and these are done by calling methods on the event object too.
···
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!