这是一些测试代码来说明我的问题;
use Tk;
use POE qw( Loop::TkActiveState );
use Tk::Toplevel;
POE::Session->create(
inline_states => {
_start => \&ui;_start
,top1 => \&top1;
,top2 => \&top2;
# ,kill_top1 => \&kill;_top1
,kill_top1 => sub {
$heap->{tl1}->destroy;
}
,over => sub { exit }
}
);
$poe_kernel->run();
exit 0;
sub ui_start {
my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
$heap->{mw} = $poe_main_window;
$but1 = $heap->{mw}->Button(
-text => 'Exit',
-width => 12,
-command => $session->postback("over")
)->pack( -padx => 7,
-side => 'left',
-expand => 0 );
$but2 = $heap->{mw}->Button(
-text => 'Top1',
-width => 12,
-command => $session->postback("top1")
)->pack( -padx => 7,
-side => 'left',
-expand => 0 );
$but2 = $heap->{mw}->Button(
-text => 'Top2',
-width => 12,
-command => $session->postback("top2")
)->pack( -padx => 7,
-side => 'left',
-expand => 0 );
$but3 = $heap->{mw}->Button(
-text => 'Kill TL',
-width => 12,
-command => $session->postback("kill_top1")
)->pack( -padx => 7,
-side => 'left',
-expand => 0 );
}
sub top1 {
my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
unless(Tk::Exists($heap->{tl1})) {
$heap->{tl1} = $heap->{mw}->Toplevel( title => "Top1");
}
}
sub top2 {
my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
$heap->{tl2} = $heap->{mw}->Toplevel( title => "Top2");
$heap->{tl1}->destroy if Tk::Exists($heap->{tl1});
}
sub kill_top1 {
my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
$heap->{tl1}->destroy if Tk::Exists($heap->{tl1});
}
如果我取消注释内联状态kill_top1的版本,一切都很好。如果我使用调用匿名子的版本(如图所示),我会得到;
C:\scripts\alias\resource>alias_poe_V-3_0_par.pl
error:Can't call method "destroy" on an undefined value at C:\scripts\alias\res
ource\alias_poe_V-3_0_par.pl line 328, line 365.
Tk::Error: Can't call method "destroy" on an undefined value at C:\scripts\alias
\resource\alias_poe_V-3_0_par.pl line 328, line 365.
Tk::After::once at C:/Perl/site/lib/Tk/After.pm line 89
[once,[{},undef,100,once,[\&POE;::Kernel::_poll_for_io]]]
("after" script)
在这篇文章中 [链接文本][1] Rocco Caputo 解释道;
“Tk 没有将事件信息传递给 POE。
如您所知,回发是匿名子例程引用,在调用 POE 事件时发布 POE 事件。它们被用作 POE 和 Tk 之间的薄而灵活的接口等。
回发是有福的,当 Tk 处理完它们时,它们的 DESTROY 方法用于通知 POE。从 Tk 的角度来看,回调和回发之间的唯一区别就是这种祝福。
由于某种原因,Tk 不会将参数传递给受祝福的回调。”
他给出了一个解决方法,但我不确定 1) 这是否是我发现的问题或 )2 如果是,如何应用该解决方法。
[1]: http://osdir.com/ml/lang.perl.poe/2004-01/msg00002.html http://osdir.com/ml/lang.perl.poe/2004-01/msg00002.html:Tk 使用 POE - 用于按键的 bind() 函数”