Before we look in detail at helloworld, we'll discuss signals and callbacks. GTK is an event driven toolkit, which means it will sleep in Gtk2::main() until an event occurs and control is passed to the appropriate function.
This passing of control is done using the idea of "signals". (Note that these signals are not the same as the Unix system signals, and are not implemented using them, although the terminology is almost identical.) When an event occurs, such as the press of a mouse button, the appropriate signal will be "emitted" by the widget that was pressed. This is how GTK does most of its useful work. There are signals that all widgets inherit, such as "destroy", and there are signals that are widget specific, such as "toggled" on a toggle button.
To make a button perform an action, we set up a signal handler to catch these signals and call the appropriate function. This is done by using a function such as:
unsigned Glib::Object->signal_connect($instance, $name, $func, $data=undef); |
where the first argument is the widget instance which will be emitting the signal, and the second the name of the signal you wish catch. The third is the function you wish to be called when it is caught, and the (optional) fourth, the data you wish to have passed to this function.
The function specified in the third argument is called a "callback function", and should generally be of the form:
sub callback_func { my ($widget, $data) = @_; #... } |
where the first argument will be a blessed reference to the widget that emitted the signal, and the second a reference to the data given as the last argument to the signal_connect() method as shown above.
Note that the above form for a signal callback function declaration is only a general guide, as some widget specific signals generate different calling parameters.
Perl supports anonymous subroutines, so it is possible to use them when defining callbacks, in this way:
$instance->signal_connect($signal_name => sub { # ... }); |
As a coding style rule of thumb, this form should be avoided for complex and or long callbacks, since it reduces code clarity. For short or simple callbacks, though, anonymous subs keep the code compact.
Remember that, when using anonymous subs, all variables in the scope of the block where the sub is defined are accessible within the anonymous sub itself. Thus, you could write:
$some_object->some_method(); $other_object->signal_connect($signal_name => sub { # ... $some_object->some_other_method(); }); |
And avoid the need to pass $some_object to the callback as a parameter.