411 REFERENCE · Wikibooks
Programming with Gtk2-Perl/Signals and Callbacks
Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.
Signals
The Gtk framework is event driven. This means it will remain idle in Gtk's main loop until an event occurs, at which point a signal will be emitted. If we have connected a callback to the signal, it will be executed before returning control back to the main loop.
In the last chapter we connected to the clicked signal of a button in order save some user input to a file.
$save_btn->signal_connect('clicked' => \&save_note, $entry);
sub save_note {
my ($save_btn, $entry) = @_;
my $text = $entry->get_text;
$entry->set_text('');
open my $OUTFILE, '>>notes.txt'
or die "could not open notes.txt for appending";
flock $OUTFILE, 2;
print $OUTFILE join '|', time, $text . "\n";
close $OUTFILE;
}
Signal Connect
Here is the syntax of the signal_connect method which is provided in the Glib::Object base class - which all widgets inherit from. In addition to the name of the signal and callback, you may optionally pass in a scalar to be passed to the callback function when it is executed.
$widget->signal_connect($signal_name, \&callback, [$data])
Callbacks
Callbacks are subroutine references that will be executed when a signal is emitted. When you define your callback function you will get the emitting widget and optionally a $data value as arguments.
sub callback {
my ($widget, $data) = @_;
#...
}
Callbacks can also be anonymous subroutines. You can then use encapsulation to avoid passing in an argument.
This approach is best used for short, simple callbacks. Take the example below.
$entry = Gtk2::Entry->new;
$button->signal_connect(clicked => sub {
print $entry->get_text, "\n";
});
Events
There also exists a set of events that you can connect callbacks to. Use the same signal_connect method in exactly the same manner as when connecting to signals. These events reflect the those of the x event mechanism. Here is a complete listing.
event
button_press_event
button_release_event
scroll_event
motion_notify_event
delete_event
destroy_event
expose_event
key_press_event
key_release_event
enter_notify_event
leave_notify_event
configure_event
focus_in_event
focus_out_event
map_event
unmap_event
property_notify_event
selection_clear_event
selection_request_event
selection_notify_event
proximity_in_event
proximity_out_event
visibility_notify_event
client_event
no_expose_event
window_state_event
Callbacks
The callback function is slightly different for events.
sub callback_func {
my ($widget, $event, $data) = @_;
# ...
return $ret;
}
The $event argument is an object that inherits from Gtk2::Gdk::Event. The actual package name will depend on the which event occurred. You can call the 'type' method on the $event to retrieve the type of event that occurred. You may also be able to call other methods on the $event that may be of interest, but that will vary depending on the type of event.
Event Types
Here is a list of possible values that could be returned from the type method.
nothing
delete
destroy
expose
motion-notify
button-press
2button-press
3button-press
button-release
key-press
key-release
enter-notify
leave-notify
focus-change
configure
map
unmap
property-notify
selection-clear
selection-request
selection-notify
proximity-in
proximity-out
drag-enter
drag-leave
drag-motion
drag-status
drop-start
drop-finished
client-event
visibility-notify
no-expose
scroll
window-state
setting
Return Values
The value returned from your callback function determines whether events should be propagated further. Returning a TRUE value will stop the propagation of events, while a FALSE value will continue one with normal event handling.
Disconnecting and Blocking
By storing the Integer value returned from the 'signal_connect' method, we can disconnect the callback later.
$id = $widget->signal_connect($signal => \&callback, $data );
$widget->signal_handler_disconnect($id);
You can also temporarily disable a callback from firing.
$widget->signal_handler_block($id);
$widget->signal_handlers_block_by_func(\&callback, $data);
$widget->signal_handler_unblock($id);
$widget->signal_handlers_unblock_by_func(\&callback, $data);