Working with the wxEvt Handler methods

The wx.EvtHandler class defines a number of methods that are not called under normal circumstances. The method of wx.EvtHandler that you will use frequently is Bind(), which creates the event bindings that we've discussed so far. The method signature is:

Bind(event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)

The Bind() function associates an event and an object with an event handler function. The event parameter is required, and is a wx.PyEventBinder instance as described in section 3.3. The handler argument, also required, is a Python callable object, usually a bound method or function. The handler must be callable with a single argument, the event object itself. The handler argument can also be None, in which case the event is disassociated from its current handler. The source parameter is the widget that is the source of the event. The parameter is used when the widget triggering the event is not the same as the widget being used as the event handler. Typically, this is done because you're using a custom wx.Frame class as the handler and are binding events from the widgets contained in the frame. The parent window's_init_is a convenient location for declaring the event bindings. However, if the parent window contains more than one source of button click events (i.e., the OK button and Cancel button), the source parameter is used to allow wxPython to differentiate between them. Following is a specific example of this method:

self.Bind(wx.EVT_BUTTON, self.OnClick, button)

The call binds a button event from the object named button (and only the object named button) to the OnClick() method of the instance being bound. Listing 3.1, adapted from code displayed in chapter 2, illustrates event binding both with and without a source parameter. You are not required to name your handler methods On<event>, but it is a common convention.

Listing 3.1 Sample event binding both with and without source objects def _init_(self, parent, id):

wx.Frame._init_(self, parent, id, 'Frame With Button size=(3 00, 100)) panel = wx.Panel(self, -1)

button = wx.Button(panel, -1, "Close", pos=(130, 15), size=(4 0, 40)) self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) self.Bind(wx.EVT_BUTTON, self.OnCloseMe, button)

A Binding the frame close event

Binding the C button event def OnCloseMe(self, event): self.Close(True)

def OnCloseWindow(self, event): self.Destroy()

O This line binds the frame close event to the self.OnCloseWindow method. Since the event is both triggered by and bound by the frame, there is no need to pass a source argument.

© This line binds the button click event from the button object to the self.OnCloseMe method. In this case, the button which generates the event is not the same as the frame which is binding it. Therefore, the button ID must be passed to the Bind method to allow wxPython to distinguish between click events on this button and click events from other buttons in the frame.

You can also use the source parameter to identify items even if the item is not the source of the event. For example, you can bind a menu event to the event handler even though the menu event is technically triggered by the frame. Listing 3.2 illustrates an example of binding a menu event.

Listing 3.2 Binding a menu event

#!/usr/bin/env python import wx class MenuEventFrame(wx.Frame):

wx.Frame._init_(self, parent, id, 'Menus', size=(3 00, 200)) menuBar = wx.MenuBar() menul = wx.Menu()

menuItem = menu1.Append(-1, "&Exit...") menuBar.Append(menu1, "&File") self.SetMenuBar(menuBar)

self.Bind(wx.EVT_MENU, self.OnCloseMe, menuItem)

def OnCloseMe(self, event): self.Close(True)

frame = MenuEventFrame(parent=None, id=-1)

frame.Show()

app.MainLoop()

The id and id2 parameters of the Bind() method specify the source of the event using an ID number, rather than the widget itself. Typically, the id and id2 are not required, since the ID of the event source can be extracted from the source parameter. However, at times using the ID directly does make sense. For example, if you are using predefined ID numbers for a dialog box, it's easier to use the ID number than to use the widget. If you use both the id and id2 numbers, you can bind an entire range of widgets to the event with numbers between the two IDs. This is only useful if the IDs of the widgets you want to bind are sequential.

The Bind() method is new in wxPython 2.5. In previous versions of wxPython, the EVT_* name is used like a function object, so that a binding call would appear as follows:

wx.EVT_BUTTON(self, self.button.GetId(), self.OnClick)

The disadvantage of the older style is that it does not look or act like an object-oriented method call. However, the older style still works in 2.5 (because the wx.EVT* objects are still callable), so you'll still see it in wxPython code.

Table 3.3 lists some of the most commonly used methods of wx.EvtHandler that you may call to manipulate the process of handling events.

Table 3.3 Commonly used methods of wx.EvtHandler

Method

Description

AddPendingEvent(event)

Places the event argument into the event processing system. Similar to ProcessEvent(), but it does not actually trigger immediate processing of the event. Instead, the event is added to the event queue. Useful for event-based communication between threads.

Bind(event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)

See full description in section 3.3.1.

GetEvtHandlerEnabled() SetEvtHandlerEnabled( boolean)

The property is True if the handler is currently processing events, False if otherwise.

ProcessEvent(event)

Puts the event object into the event processing system for immediate handling.

OLDER EVENT BINDING

Was this article helpful?

+4 0

Post a comment