Calling an event handler

I think this is largely a question of elegance, but I can't seem to see
what the "accepted approach" is here.

Suppose I have an event handler on (say) a ListBox, and this event handler
updates some other window when an item is added to or deleted from the
ListBox. So the "prototype" for the handler looks like 'Update(self,
event)'.

Now suppose that there are other circumstances when I want to invoke this
handler -- like when I programmatically alter the list and reset the
selection (in which case the wxEVT_COMMAND_LISTBOX_SELECT event does not
get emitted). (One could argue that there could be an option on these
methods to emit the event, but let's not go there now. I'm sure there are
arguments on both sides of that issue.)

So what is the "elegant" thing to do?

1. Just call the method directly with 'None' as the second (event)
parameter?
2. Create a fake event object and call the method with it as the second
parameter?
3. Force the emission of the event.

There's not too much point (in general) in doing 2 since it doesn't gain
you anything over 1 and just takes more time. Choice 3 was my first
inclination, but I can't seem to figure out how (after looking through the
demos and my stack of Python doc) to force an event emission. 1 will do
the job, but it seems -- I don't know -- somehow a bit tacky. :slight_smile:

···

--------------------------------------
Gary H. Merrill
Director and Principal Scientist, New Applications
Data Exploration Sciences
GlaxoSmithKline Inc.
(919) 483-8456

If the handler doesn't use any methods or attributes of the event, 1 is fine. Otherwise, what I usually do is have the event handler call another method to do the actual work. Then, I can just call that other method directly in other circumstances.

David

···

gary.h.merrill@gsk.com wrote:

I think this is largely a question of elegance, but I can't seem to see
what the "accepted approach" is here.

Suppose I have an event handler on (say) a ListBox, and this event handler
updates some other window when an item is added to or deleted from the
ListBox. So the "prototype" for the handler looks like 'Update(self,
event)'.

Now suppose that there are other circumstances when I want to invoke this
handler -- like when I programmatically alter the list and reset the
selection (in which case the wxEVT_COMMAND_LISTBOX_SELECT event does not
get emitted). (One could argue that there could be an option on these
methods to emit the event, but let's not go there now. I'm sure there are
arguments on both sides of that issue.)

So what is the "elegant" thing to do?

1. Just call the method directly with 'None' as the second (event)
parameter?
2. Create a fake event object and call the method with it as the second
parameter?
3. Force the emission of the event.

Now suppose that there are other circumstances when I want to invoke this
handler -- like when I programmatically alter the list and reset the
selection (in which case the wxEVT_COMMAND_LISTBOX_SELECT event does not
get emitted). (One could argue that there could be an option on these
methods to emit the event, but let's not go there now. I'm sure there are
arguments on both sides of that issue.)

So what is the "elegant" thing to do?

1. Just call the method directly with 'None' as the second (event)
parameter?

One way to do this is to define your handler like this:

  def DoSomething(self, *evt):
    DoIt()

Then the second parameter is optional and you can just call self.DoSomething() if you want.

2. Create a fake event object and call the method with it as the second
parameter?
3. Force the emission of the event.

There's not too much point (in general) in doing 2 since it doesn't gain
you anything over 1 and just takes more time. Choice 3 was my first
inclination, but I can't seem to figure out how (after looking through the
demos and my stack of Python doc) to force an event emission.

It depends on the class and the type of event. Some classes have a helper method that will create and send an event, but usually they are meant for internal use and so are not very conistent.

If there are times when you really do want to send an event (so multiple handlers can see it, etc.) then the way to do it is to create an event object of the right type, set it's attributes, (at least the eventType and the ID) and then do this:

  theControl.GetEventHandler().ProcessEvent(event)

to cause the event to be sent immediately, or this:

  wxPostEvent(theControl, event)

to add the event to a pending events list that will get processed later.

···

gary.h.merrill@gsk.com wrote:

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

I just do this, but with a slight tweak:

   def update(self, event=None):
      # blah blah

So then I can say things like:

   self.update()
   ...
   EVT_FOOBAR(self, thing.GetId(), self.update)

Of course, that only works for methods that don't need any interesting info from the event.

···

On Wednesday 30 April 2003 06:40 am, gary.h.merrill@gsk.com wrote:

1. Just call the method directly with 'None' as the second (event)
parameter?

--
Chuck
http://ChuckEsterbrook.com