如何undersand的POE-TK用破坏?(How to undersand the POE-Tk

2019-09-19 10:09发布

下面是一些测试代码来说明我的问题;


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]罗科·卡普托解释;

“TK不流通的事件信息POE。

如你所知,回发是后POE的事件,他们是所谓当匿名函数引用。 他们作为POE和Tk之间的薄,灵活的接口,除其他事项外。

回发福,并且它们的destroy方法被用来当传统知识和他们所做的通知POE。 传统知识的角度来看,回调和回发之间唯一的区别是这个祝福。

出于某种原因,传统知识不传递参数给一个幸福的回调“。

他给出了一个解决办法,但我不知道1)如果这是我发现的问题或)2,如果是,如何应用这些解决方法。

[1]: http://osdir.com/ml/lang.perl.poe/2004-01/msg00002.html :TK随着POE -用于按键bind()函数”

Answer 1:

它看起来确实像你这样打的罗科是说明问题。 基本上,你的封(次{...})访问$堆,因为$堆的范围是在创建关闭。 在另一方面,当您使用与kill_top1函数引用看来你没有得到过任何参数,这意味着@_ [HEAP]是不确定的。

使用闭合似乎工作,但如果你想“假”的话,你可以将其替换为:

kill_top1 => sub { 
    @args[KERNEL,SESSION,HEAP] = ($kernel,$session,$heap);
    kill_top1(@args);
}

这将是我的偏好,只是为了保持接口和事件处理的,kill_top1同所有其他。



文章来源: How to undersand the POE-Tk use of destroy?
标签: perl tk poe