2009-07-17 3 views
2

私の問題を説明するためのテストコードです。POE-Tkが破壊を使用するのをどのようにアンダーサンドしますか?


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の間に薄い、柔軟なインターフェースとして使用していますTkの観点から見ると、コールバックとポストバックの唯一の違いは、この祝福です。

何らかの理由で、Tkはブレスクドコールバックにパラメータを渡しません。 "

彼は回避策を示していますが、私にはわかりません1)これが明らかになっている問題であるか、2つある場合は回避策の適用方法です。

[1]:http://osdir.com/ml/lang.perl.poe/2004-01/msg00002.html:TkのではPOE - キー入力のためのバインド()関数」それはあなたがロッコは基本的に記述された問題をヒットしているように見えます

+1

最初の$ヒープ - > {tl1} - >破壊すると、$ヒープはどこから得られますか?どこにでも定義されているのはわかりません。 – Inshallah

+0

コンマをどこに置いても何が問題になりますか?彼らは私の目を傷つける。 –

+0

もちろん、行の最後にカンマを置くことには何も問題ありません。ウィジェットへの設定のグループをカットアンドペーストして、スタックの途中にカンマなしの行を残してしまったときに、構文エラーを作成した後、最初にそれらを配置し始めました。これがあなたに不快感を与えた場合はお詫び申し上げます。 - jpolache 0秒ago [コメントを削除] – jpolache

答えて

3

、あなたの閉鎖(サブ{.. 。})は、$ heapにアクセスすることができます。これは、クロージャを作成するときに$ heapがスコープ内にあるからです。一方、& kill_top1関数参照を使用すると、渡されたパラメータが得られないように見えます。 HEAP]は未定義であるクロージャを使用して

が動作しているようですが、あなたはそれを「偽」したい場合、あなたはでそれを置き換えることができます:。

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

これは、他のすべてのものと同じように、kill_top1へのインターフェイスとイベント処理を保持することが私の好みです。

関連する問題