使用 Gtk2-Perl/Signals 和 Callbacks 进行编程
外观
Gtk 框架是事件驱动的。这意味着它将在 Gtk 的主循环中保持空闲,直到发生事件,此时将发出一个信号。如果我们已将回调连接到信号,它将在将控制权返回主循环之前执行。
在上一章中,我们连接到按钮的 clicked 信号以将一些用户输入保存到文件中。
$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;
}
以下是 Glib::Object 基类中提供的 signal_connect 方法的语法 - 所有小部件都继承自它。除了信号和回调的名称之外,您还可以选择传递一个标量,当回调函数执行时将其传递给回调函数。
$widget->signal_connect($signal_name, \&callback, [$data])
回调是子例程引用,当发出信号时将执行。当您定义回调函数时,您将获得发出小部件和可选的 $data 值作为参数。
sub callback {
my ($widget, $data) = @_;
#...
}
回调也可以是匿名子例程。然后,您可以使用封装来避免传入参数。这种方法最适合简短简单的回调。请看下面的例子。
$entry = Gtk2::Entry->new;
$button->signal_connect(clicked => sub {
print $entry->get_text, "\n";
});
还存在一组事件,您可以将回调连接到这些事件。以与连接到信号完全相同的方式使用相同的 signal_connect 方法。这些事件反映了 x 事件机制的那些事件。以下是完整的列表。
|
|
|
回调函数对于事件略有不同。
sub callback_func {
my ($widget, $event, $data) = @_;
# ...
return $ret;
}
$event 参数是一个继承自 Gtk2::Gdk::Event 的对象。实际的包名称将取决于发生了哪个事件。您可以对 $event 调用 'type' 方法来检索发生的事件类型。您还可以对 $event 调用其他可能感兴趣的方法,但这将根据事件类型而有所不同。
以下列出了 type 方法可能返回的可能值。
|
|
|
|
从回调函数返回的值决定事件是否应进一步传播。返回 TRUE 值将停止事件传播,而 FALSE 值将继续进行正常的事件处理。
通过存储从 'signal_connect' 方法返回的 Integer 值,我们可以在以后断开回调连接。
$id = $widget->signal_connect($signal => \&callback, $data );
$widget->signal_handler_disconnect($id);
您还可以暂时禁用回调的触发。
$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);