BInd() vs Widget.Bind()

I saw the discussion on the wiki about this, but I’m still not sure I understand the why’s and wherefores of it all.

I have one Panel that has the following code in it…

    self.Bind(wx.EVT_CHOICE, self.adjust_ability_lists, id=ABILITY_ID)

It works beautifully any time any widget with the id of ABILITY_ID is selected adjust_ability_lists is called.

Building on that work I created another Panel it had the following code in it…

 self.Bind(wx.EVT_CHOICE, self.adjust_available_classes, id=ALIGNMENT_ID)

It didn’t work so well. adjust_available_classes was NEVER called.

I changed the code above to be…

 self.EthicsChoice.Bind(wx.EVT_CHOICE, self.adjust_available_classes)

and everything worked just as I expected it to.

I’m sure this has to do with both Panels being part of the same Frame and something about Event propagation I don’t understand, but I hate having two different idioms in my code and would love to either a) understand enough about what was going on in the first case to fix it or b) understand enough of the pitfalls or problems (if there are any) in my second example to convert all my other working code that uses the first idiom into the second.

···


Stand Fast,
tjg.

Timothy Grant wrote:

I have one Panel that has the following code in it...

        self.Bind(wx.EVT_CHOICE, self.adjust_ability_lists, id=ABILITY_ID)

It works beautifully any time any widget with the id of ABILITY_ID is selected adjust_ability_lists is called.

This seems to be asking for trouble -- do you really have more than one widget with ABILITY_ID? I think having multiple widgets with the same ID can be dangerous. One reason I never use explicit IDs:

http://wiki.wxpython.org/wxPython%20Style%20Guide
(section 3)

The one reason to use IDs that I've seen is that there are places where you can specify a range of IDs, and it can be useful there (though I've never done that, I don't recall where you can!).

So, if you really want multiple widgets to call the same handler, I'd just write that in the code, maybe in a loop:

for w in List_of_ability_widgets:
     w.Bind(wx.EVT_CHOICE, self.adjust_ability_lists)

Or is there really only one AbilityList widget anyway?

     self.Bind(wx.EVT_CHOICE, self.adjust_available_classes, id=ALIGNMENT_ID)

It didn't work so well. adjust_available_classes was NEVER called.

are you sure that self.EthicsChoice has ID == ALIGNMENT_ID, but anyway, I'd avoid that style anyway.

I changed the code above to be...

     self.EthicsChoice.Bind(wx.EVT_CHOICE, self.adjust_available_classes)

Which is the style I recommend.

by the way, if you really want to use the self,.Bind style, you can do:

self.Bind(wx.EVT_CHOICE,
           self.adjust_available_classes,
           self.EthicsChoice.Bind)

i.e. you can pass in the widget itself, rather than its ID. I only do that for menus, though, because MenuItems don't have a Bind() method.

understand enough of the pitfalls or problems (if there are any) in my second example to convert all my other working code that uses the first idiom into the second.

I think there are far more pitfall in the first idiom, so I think converting is a fine idea.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov