我想为我的Perl / Tk程序实现历史记录/最近文件功能。
以下是我的程序的工作代码摘录,用于演示我的问题。
#!/usr/bin/perl
use strict;
use warnings;
use English qw( -no_match_vars );
use Tk;
my @history_entries = qw(Back To The History);
my $mw = MainWindow->new();
my $menubar = $mw->Menu();
$mw->configure( -menu => $menubar );
my $file = $menubar->cascade( -label => '~File' );
my $history = $file->cascade( -label => '~History', );
build_history();
MainLoop();
#=== FUNCTION ================================================================
# NAME: build_history
# PURPOSE: Polulate the history
#===============================================================================
sub build_history {
foreach (@history_entries) {
$history->command(
-label => $ARG,
-command => \&some_function,
-compound => 'left',
);
}
return;
} # ---------- end of subroutine build_history ----------
如您所见,条目是使用$history->command创建的,但每次调用build_history时如何删除它们?
我希望删除它们的原因是每次用户打开文件时,应删除最后一项(在本例中为“历史记录”),并将新项目放在列表顶部。所以我最多有(在这个例子中)四个条目。
欢迎使用Tk实现此功能的任何其他方式。
感谢您的时间。
更新: 我遵循了“mu”的建议,并尝试在调用函数之后使用children()函数获取子部件,如下所示:
my @child = $history->children();
foreach my $c ( @child ) {
if ($c->Exists()){
$c->destroy;
}
}
程序退出时出现错误:
Can't locate object method "children" via package "Tk::Menu::Cascade" at /home/alex/Desktop/stack_history.pl line 28.
答案 0 :(得分:2)
您可以先从菜单栏创建一个子菜单:
my $sub_menu = $menubar->Menu(-tearoff => 0);
然后你可以将这个子菜单传递给级联menuitem:
$file->cascade( -label => '~History', -menu => $sub_menu);
然后您可以在子菜单中添加/删除菜单项:
foreach (@history_entries) {
$sub_menu->command(
-label => $ARG,
-compound => 'left',
);
}
...
$sub_menu->delete(0); # Remove first element
使用此解决方案,您可以避免重新整理整个菜单。
答案 1 :(得分:0)
我最终重建了整个菜单。这就是我的代码看起来像atm的方式。我并不为此感到骄傲,但它有效...我愿意接受任何形式的建议。
#!/usr/bin/perl
use strict;
use warnings;
use English qw( -no_match_vars );
use Tk;
# History entries are stored in array
my @history_entries = qw(Back To The History);
my $mw = MainWindow->new();
$mw->geometry('200x200');
my $menubar = $mw->Menu();
#Build menus
$mw->configure( -menu => $menubar );
build_menu();
$mw->Button(
-text => 'Update History',
-command => \sub {
#when a user opens a file insert_history is called.
insert_history();
}
)->pack( -side => 'bottom', -anchor => 'sw' );
MainLoop();
#=== FUNCTION ================================================================
# NAME: build_menu
# PURPOSE: Update/Build the menu
#===============================================================================
sub build_menu {
#delete the whole menu
$menubar->delete(1);
#built it again
my $file = $menubar->cascade( -label => '~File' );
my $history = $file->cascade( -label => '~History', );
foreach (@history_entries) {
$history->command(
-label => $ARG,
-compound => 'left',
);
}
return;
} # ---------- end of subroutine build_menu ----------
#=== FUNCTION ================================================================
# NAME: insert_history
# PURPOSE: Do something with the array containing the history entries.
# Then rebuild the menu.
#===============================================================================
sub insert_history {
#make something with the array
my $last_element = pop @history_entries;
unshift @history_entries, $last_element;
#update menu
build_menu();
return;
} # ---------- end of subroutine insert_history ----------