Chapter 4. Events

Introduction

In this example we will add simple event handling. In wxPerl this is done through the use of event connectors. This is just a bunch of functions (one for each event type) that define object methods to be called in response to certain events.

Program

The first thing to do in order to use events is importing the event connectors. All these functions are exported by the Wx::Event module.

package MyFrame;

use base 'Wx::Frame';
# import the event registration function
use Wx::Event qw(EVT_BUTTON);

The second step for using events is connecting an object method with an event; this way when some window fires an event the method will be called.

    my $button = Wx::Button->new( $panel,         # parent window
                                  -1,             # ID
                                  'Click me!',    # label
                                  [30, 20],       # position
                                  [-1, -1],       # default size
                                  );

    # register the OnClick method as an handler for the
    # 'button clicked' event. The first argument is a Wx::EvtHandler
    # that receives the event
    EVT_BUTTON( $self, $button, \&OnClick );

    return $self;
}

The EVT_BUTTON call above means that, when a "button clicked" event is fired by $button, the method $self->OnClick is called.

All event handlers always have two arguments: the first is the receiver for the event (the first parameter for the event connector), the second is an event object specific for the received event type. For button clicks (and various other events) it is a Wx::CommandEvent.

sub OnClick {
    my( $self, $event ) = @_;

    $self->SetTitle( 'Clicked' );
}

And finally here is how this looks on screen.

(Mac OS X 10.3)

Here you can see the program at a glance (it is suffixed .pl.txt so your browser will not try to execute it, but from Perl's point of view this makes no difference).

About event connectors

All event connectors always take a Wx::EvtHandler as their first argument; most of the time this is just a Wx::Window subclass. This event is the object that will be passed as the first parameter to the event handler. Some events (like mouse motion events) can only be caught by the window generating them. Most kind of events however (like button click events) travel up the window hierarchy and can be caught by any ancestor of the control generating them. This means that wxPerl needs a way to distinguish which control generated a specific event. The answer lies in the second argument in the call to EVT_BUTTON, which is the button itself.

Every Wx::Window has an ID (the second argument to the constructor, always -1 in the examples so far) which identifies it inside the program. wxWidgets uses window IDs to distinguish the originators of events. This means that the program above could have passed a specific ID to Wx::Button::new and as the second argument to EVT_BUTTON. However keeping track of used IDs tends to be awkward and most of the time it is much simpler to let wxPerl sort things out (as in the example).