[wx-dev] about event table macros
Robin Dunn
robin at alldunn.com
Tue Aug 7 11:41:44 PDT 2007
Vadim Zeitlin wrote:
> On Tue, 31 Jul 2007 16:50:52 -0700 Robin Dunn <robin at alldunn.com> wrote:
>
> RD> > So maybe it's indeed worth doing it. Or maybe we could just add wxEVT_MENU
> RD> > as synonym for wxEVT_COMMAND_MENU_SELECTED.
> RD>
> RD> Not that it matters much for this discussion but just for comparrison in
> RD> wxPython it looks like this:
>
> Thanks for reminding us about wxPython, it would indeed be nice to make
> this consistent across all (or at least most) of the language bindings too.
> For the reference, in wxPerl this is done with
>
> EVT_MENU($this, $ID_EXIT, \&OnExit);
>
> (you could fully qualify it as Wx::Event::EVT_MENU too). It's pretty
> similar to the Python version except that the arguments are in C++ order
> (I agree that wxPython order makes better sense...)
>
> RD> * Because of how wx is imported the equivalent of EVT_MENU is written
> RD> wx.EVT_MENU.
> RD>
> RD> * Originally it was a function that called Connect and was used like this:
> RD> wx.EVT_MENU(self, self.OnExit, wx.ID_EXIT)
>
> I guess something is missing here as I don't see "Connect" anywhere?
It was done inside the function call. When EVT_MENU was a function it
looked like this:
def EVT_MENU(win, id, func):
win.Connect(id, -1, wxEVT_COMMAND_MENU_SELECTED, func)
And now it is just this:
EVT_MENU = wx.PyEventBinder( wxEVT_COMMAND_MENU_SELECTED, 1)
but Connect is still used in the PyEventBinder class.
>
> RD> * Now it is an instance of a wx.PyEventBinder class, and Connect is
> RD> still called under the covers but it is more hidden from the programmer.
> RD> The class has a __call__ method so the instance can still be called as
> RD> a function like the above, but it is more commonly passed to a Python
> RD> specific method called Bind, like this:
> RD>
> RD> self.Bind(wx.EVT_MENU, self.OnExit, menuItem)
> RD> or
> RD> self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT)
> RD> etc.
>
> Hmm, any reason this "Bind" isn't called "Connect" (as in C++)?
IIRC I didn't feel like it was a valid overload of the name, since Bind
is doing a bit more than Connect, and since the parameter order changed.
> Also, why
> is it preferable doing it like this instead of wx.EVT_MENU(...) which seems
> pretty clear to me?
Some people feel that calling a method is more OO than calling a
function. Also, by calling a method of the instance that the handler
object is to be bound to, it better implies where the event has to
travel to in the containment hierarchy before that handler is called.
>
> RD> * If needed the value of wxEVT_COMMAND_MENU_SELECTED can be retrieved
> RD> from the binder object as wx.EVT_MENU.typeId.
>
> I wonder how is it defined for e.g. EVT_MOUSE_EVENTS() which has a dozen
> or so of associated wxEVT_XXX constants?
There is actually a list of event type IDs in the object, and the typeId
is a property that gets the first (and usually only) item in that list.
The list itself is also accessible.
>
> Anyhow, it seems clear that we should be using EVT_MENU as nobody knows
> about wxEVT_COMMAND_MENU_SELECTED. And I still think we should add
> wxEVT_MENU as synonym for the latter.
Yes, I've always used the EVT_WHATEVER name in conversation and in
writing as if it were the event type. That has greatly helped to reduce
confusion in newbies and others because what is talked about is exactly
what they need to use in their code, not some ID with with a similar
name that they need to translate or look up in the docs, and not a
common event handler method name like OnWhatever that they would have to
guess which event type is being referred to. In other words I would
always say something like, "In your EVT_PAINT handler..." or "You need
to catch the EVT_SIZE event" rather than saying something like "In your
OnPaint..." or "You need to have an OnSize." It makes it much easier to
be more specific and generate less confusion or work.
> But the question about
> EVT_MOUSE_EVENTS actually applies to C++ too -- there is currently no way
> to do the same thing as this macro does using Connect(). I'm not sure if
> it's a real problem though.
That's one reason why turning the EVT_WHATEVER into an instance of an
object has worked well for wxPython. It can easily have a loop that
calls Connect multiple times.
--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!
More information about the wx-dev
mailing list