使用 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);