schweini has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monks,

I'm trying to build myself a handy little define-the-keyboard-traversal-path method for a Tk-app i'm doing right now that i may call like this:

&defineOrder(\$widget1, \$widget2, \$widget3)
my first brainstorm produced this:
sub defineOrder { for (my $i = 0; defined($_[$i+1]); $i++) { ${$_[$i]}->bind('<Return>', sub { ${$_[$i+1]}->focus } ); } ${$_[0]}->focus; }

...which - of course - wont do, because my forgetful, confused program of course doesn't remember what @_ looked like the moment i binded that anon-sub to this event.

so i tried this: (methinks this is ugly)

&defineOrder(qw/$widget1 $lwidget2 $widget3/); sub defineOrder { for (my $i = 0; defined($_[$i+1]); $i++) { my $evalString = $_[$i]."->bind( '<Return>', sub { ".$_[$i+1]. +"->focus } );"; print "$evalString\n"; eval $evalString; print "$@\n" if $@; } }

...which, in turn, wont do since the widgets seem to be out of scope inside the sub (as they should be).

anybody have an idea what i can do about this?
i'm not really into using $widget->focusNext since i simply don't like the notion of the focusorder being defined by the order i pack-ed or place-ed the widgets.
(or is there any way to re-shuffle the stacking order?)

wanting to see the light of knowledge, but feeling as if he were inside a black hole,

-schweini

Replies are listed 'Best First'.
Re: changing the focusing-order in Tk
by hiseldl (Priest) on Sep 26, 2002 at 02:48 UTC
    You should be able to pass the reference to the bind command without the anon sub. It should look something like this:
    &defineOrder($widget1, $widget2, $widget3) # sub defineOrder { for (my $i = 0; defined($_[$i+1]); $i++) { # REMOVE the anonymous sub call and replace with # reference to widget which has its own scope ${$_[$i]}->bind('<Return>', \${$_[$i+1]}->focus ); } ${$_[0]}->focus; }

    this should make the widget scoping work better. This isn't tested so YMMV.

    --
    hiseldl
    "Act better than you feel"

      thanks a lot! (++)
      darn.
      i was mistaken - it DOESN'T work that way!
      (i was a bit confused, and forgot to actually call that sub, and still had some hardcoded define-the-focus-order code flying around in a dark corner of my script, so i didn't even notice that it didn't.
      help, anyone?
      please?

      -schweini
        okay, here's a script illustrating the problem:
        use Tk; use strict; use warnings; my $win = MainWindow->new(); $win->Button(-text => 'Other Window', -command => \&otherwindow)->pack +; sub otherwindow { my $otherwin = $win->Toplevel; my $foo = $otherwin->Entry->pack; my $bar = $otherwin->Entry->pack; my $baz = $otherwin->Entry->pack; &defineOrder(\$foo, \$bar, \$baz); } sub defineOrder { for (my $i = 0; defined($_[$i+1]); $i++) { ${$_[$i]}->bind('<Return>' , \${$_[$i+1]}->focus ); print ${$_[$i]}, "\n"; } ${$_[0]}->focus; # BTW: $foo->focus() wont work here.... } MainLoop();

        i'm starting to think this is a scoping problem - but then aain, this script doesn't throw ANY warnings.
        dazzled,

        -schweini