使用 Gtk2-Perl 编程/入门/快速说明
在运行此脚本或阅读下面的解释之前,请通读程序并尝试理解它在做什么。在你认为自己弄明白后,尝试运行它。当你按下 Alt+s 或 Alt+x 时会发生什么?当你改变窗口大小的时候你注意到什么了吗?
use warnings;
use strict;
use Glib qw(TRUE FALSE);
use Gtk2 '-init';
my $window = Gtk2::Window->new;
$window->set_title('Quick Note');
$window->signal_connect('delete-event' => sub { $_[0]->destroy });
$window->signal_connect('destroy' => sub { Gtk2->main_quit });
my $hbox = Gtk2::HBox->new;
my $label = Gtk2::Label->new('Note');
my $entry = Gtk2::Entry->new();
my $save_btn = Gtk2::Button->new_with_mnemonic('_Save');
$save_btn->signal_connect('clicked' => \&save_note, $entry);
my $exit_btn = Gtk2::Button->new_with_mnemonic('E_xit');
$exit_btn->signal_connect('clicked' => sub { $window->destroy });
$hbox->pack_start($label , FALSE, FALSE, 0);
$hbox->pack_start($entry , TRUE , TRUE , 0);
$hbox->pack_start($save_btn, FALSE, FALSE, 0);
$hbox->pack_start($exit_btn, FALSE, FALSE, 0);
$window->add($hbox);
$window->show_all;
Gtk2->main;
sub save_note {
my $save = shift;
my $entry = shift;
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;
}
在这个脚本中,我们介绍了一些新的窗口部件。HBox 是一个容器窗口部件,我们用它来控制窗口中其他窗口部件的布局。另外两个是 Entry 和 Button 窗口部件,它们允许用户与程序交互。
use Glib qw(TRUE FALSE);
Glib 是 Gtk 的一个依赖项。我们在程序中包含这一行是为了获取对常量 TRUE 和 FALSE 的访问权限。你可以简单地使用布尔值 1 和 0,但为了清晰起见,我们将使用 TRUE 和 FALSE。
$window->signal_connect('delete-event' => sub { $_[0]->destroy });
$window->signal_connect('destroy' => sub { Gtk2->main_quit });
你可以看到,我们在绑定到信号/事件时采用了略微不同的方法。在这里,我们在 'delete-event' 发生时调用窗口的 destroy 方法(它会发出 'destroy' 信号)。连接到 'destroy' 信号,我们有指示在 Gtk 的主循环中退出运行的指令。使用这种方法是因为我们希望程序在应用程序窗口以任何方式销毁时退出,而不仅仅是在用户按下窗口标题栏中的关闭按钮时退出。稍后,我们将连接到 $exit_btn 的 'clicked' 信号,以销毁窗口,从而退出应用程序。
尽管使用相同的方法进行连接,但事件和信号之间确实存在区别(这些信号与 Unix 系统信号不同,也不使用它们来实现,但术语非常相似)。后面会对此进行更多介绍。
my $save_btn = Gtk2::Button->new_with_mnemonic('_Save');
这将创建一个新的 Button 窗口部件,它有标签 'Save'。请注意,我们在这里使用了 'new_with_mnemonic' 方法。这将设置键盘快捷键 Alt+s 来触发按钮上的 'clicked' 事件。'Save' 中的 'S' 也将被下划线,以提醒最终用户键盘快捷键的存在。
因为我们正在使用 Perl 绑定,所以我们可以简单地说
my $save_btn = Gtk2::Button->new('_Save');
这是因为 Perl 绑定意识到我们实际上想要使用底层 C 库中提供的 'new_with_mnemonic' 构造函数。其他也具有 'new_with_mnemonic' 或 'new_with_label' 构造函数的窗口部件通常也允许你这样做。许多人仍然更喜欢使用 'new_with_label' 或 'new_with_mnemonic' 构造函数,无论如何。
$save_btn->signal_connect('clicked' => \&save_note, $entry)
在这里,我们使用子程序的引用而不是匿名的子程序。$entry 将在回调执行时作为参数传递。
my $exit_btn = Gtk2::Button->new_with_mnemonic('E_xit');
$exit_btn->signal_connect('clicked' => sub { $window->destroy });
现在你应该清楚这两行代码的作用了。
$hbox->pack_start($label , FALSE, FALSE, 0);
$hbox->pack_start($entry , TRUE , TRUE , 0);
$hbox->pack_start($save_btn, FALSE, FALSE, 0);
$hbox->pack_start($exit_btn, FALSE, FALSE, 0);
这两行代码将我们的界面窗口部件打包到 HBox 窗口部件中。语法是
$container->pack_start($widget, $expand, $fill, $padding)
如果 $expand 参数为 FALSE,则容器将收缩到窗口部件周围。如果 $expand 参数为 TRUE,则容器将在窗口部件周围扩展,以填充其父级分配的空间。当 $fill 参数为 TRUE 时,容器内的额外空间将分配给子窗口部件。当设置为 FALSE 时,额外空间将作为容器窗口部件的填充保留。只有当 $expand 参数也为 TRUE 时,$fill 参数才会生效。
在我们的示例中,$entry 对象被打包,$expand 和 $fill 参数设置为 TRUE。当你改变窗口大小时,$entry 周围的框会扩展,使 $entry 填充剩余区域。其他对象,它们被打包的 $expand 和 $fill 值为 FALSE,将保持其自然大小。
sub save_note {
my $save = shift;
my $entry = shift;
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;
}
如果你不清楚这里发生了什么,建议你浏览一下 Perl 编程。