http://www.perlmonks.org?node_id=932366

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

I create a HList and put widgets (example Entrys) in it. Now when i use the tab key the focus jumps backward.
Is there a solution to get the focus jump forward?
When i use this for create Forms the direction is very important.
Here a little Example:
use strict; use warnings; use Tk; use Tk::HList; my $mw = MainWindow->new(); my $hlist = $mw->HList( -header => 0, -columns => 1 )->pack; $hlist->add(0); $hlist->itemCreate(0, 0, -itemtype => 'window', -widget => $hlist->Ent +ry(-text => "Text0") ); $hlist->add(1); $hlist->itemCreate(1, 0, -itemtype => 'window', -widget => $hlist->Ent +ry(-text => "Text1") ); $hlist->add(2); $hlist->itemCreate(2, 0, -itemtype => 'window', -widget => $hlist->Ent +ry(-text => "Text2") ); MainLoop;

Replies are listed 'Best First'.
Re: Tab Order for Widgets in HList
by zentara (Archbishop) on Oct 19, 2011 at 14:01 UTC
    Not to hijack the thread, but I ran into some Tab troubles when trying to work on this problem. The code below is supposed to be a general purpose routine for defining focus order, but if you try it, it works for the Enter key, but not Tab! Can anyone enlighten me as to why Tab is hard coded to pass focus the way it does?
    #!/usr/bin/perl use Tk; use strict; use warnings; #changes focus on Return(Enter) key but not Tab my $win = MainWindow->new(); my $foo = $win->Entry->pack; my $bar = $win->Entry->pack; my $baz = $win->Entry->pack; my $boo = $win->Entry->pack; my $baa = $win->Entry->pack; &defineOrder($foo,$baa,$bar,$boo,$baz); sub defineOrder { my $widget; for (my $i=0; defined( $_[$i+1] ); $i++) { $_[$i]->bind('<Key-Return>', [\&focus, $_[$i+1]]); # won't work with Tab $_[$i]->bind('all', '<Tab>', [\&focus, $_[$i+1]]); } # Uncomment this line if you want to wrap around $_[$#_]->bind('<Key-Return>', [\&focus, $_[0]]); $_[0]->focus; } sub focus { my ($tk, $self) = @_; $self->focus; } MainLoop();

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh

      I'm not sure what is going on, but its something :)

      tab x 5, enter x 10

      MainWindow=HASH(0xe911ac) bindtags ( MainWindow , . , all , ) Tk::Entry=HASH(0xed9414) bindtags ( Tk::Entry , .entry , . , all , ) Tk::Entry=HASH(0xed96b4) bindtags ( Tk::Entry , .entry4 , . , all , ) Tk::Entry=HASH(0xed95f4) bindtags ( Tk::Entry , .entry1 , . , all , ) Tk::Entry=HASH(0xed9664) bindtags ( Tk::Entry , .entry3 , . , all , ) Tk::Entry=HASH(0xed9644) bindtags ( Tk::Entry , .entry2 , . , all , ) MainWindow=HASH(0xe911ac) = $win Tk::Entry=HASH(0xed9414) = $foo Tk::Entry=HASH(0xed95f4) = $bar Tk::Entry=HASH(0xed9644) = $baz Tk::Entry=HASH(0xed9664) = $boo Tk::Entry=HASH(0xed96b4) = $baa focus Tk::Entry=HASH(0xed9414) Tk::Entry=HASH(0xed9644) focus Tk::Entry=HASH(0xed9644) Tk::Entry=HASH(0xed9644) focus Tk::Entry=HASH(0xed9644) Tk::Entry=HASH(0xed9644) focus Tk::Entry=HASH(0xed9644) Tk::Entry=HASH(0xed9644) focus Tk::Entry=HASH(0xed9644) Tk::Entry=HASH(0xed9644) focus Tk::Entry=HASH(0xed9644) Tk::Entry=HASH(0xed9414) focus Tk::Entry=HASH(0xed9414) Tk::Entry=HASH(0xed96b4) focus Tk::Entry=HASH(0xed96b4) Tk::Entry=HASH(0xed95f4) focus Tk::Entry=HASH(0xed95f4) Tk::Entry=HASH(0xed9664) focus Tk::Entry=HASH(0xed9664) Tk::Entry=HASH(0xed9644) focus Tk::Entry=HASH(0xed9644) Tk::Entry=HASH(0xed9414) focus Tk::Entry=HASH(0xed9414) Tk::Entry=HASH(0xed96b4) focus Tk::Entry=HASH(0xed96b4) Tk::Entry=HASH(0xed95f4) focus Tk::Entry=HASH(0xed95f4) Tk::Entry=HASH(0xed9664) focus Tk::Entry=HASH(0xed9664) Tk::Entry=HASH(0xed9644)

      This works

      sub defineOrder { my $widget; for (my $i=0; defined( $_[$i+1] ); $i++) { $_[$i]->bind( '<Key-Return>', [\&focus, $_[$i+1]]); $_[$i]->bind( '<Tab>', [\&focus, $_[$i+1]]); } # Uncomment this line if you want to wrap around $_[ $#_ ]->bind('<Key-Return>', [\&focus, $_[0]]); $_[ $#_ ]->bind('<Tab>', [\&focus, $_[0]]); $_[0]->focus; }

      Using defineOrder($win, $foo,$baa,$bar,$boo,$baz); eliminates the need for the wraparound portion

Re: Tab Order for Widgets in HList
by Anonymous Monk on Oct 19, 2011 at 13:30 UTC
    Here is a stupid way to do it :)
    #!/usr/bin/perl -- use strict; use warnings; use Tk; use Tk::HList; my $mw = MainWindow->new(); my $hlist = $mw->HList( -header => 0, -columns => 1 )->pack( qw/-expan +d 1 -fill both /); $hlist->add(0); $hlist->itemCreate(0, 0, -itemtype => 'window', -widget => $hlist->Ent +ry(-text => "Text0") ); $hlist->add(1); $hlist->itemCreate(1, 0, -itemtype => 'window', -widget => $hlist->Ent +ry(-text => "Text1") ); $hlist->add(2); $hlist->itemCreate(2, 0, -itemtype => 'window', -widget => $hlist->Ent +ry(-text => "Text2") ); $mw -> bind('all','<Tab>', sub { no warnings 'uninitialized'; $hlist->focus; my $origSel = $hlist->info('anchor'); $hlist->UpDown('next'); my $newSel = $hlist->info('anchor'); if( ( $origSel and $newSel ) and ( $origSel == $newSel ) ){ $hlist->selectionClear; $hlist->anchorClear; $hlist->UpDown('next'); # go back to zero } Tk::break(); }); MainLoop; __END__
      And the smart way
      $mw -> bind('all','<Tab>', sub { $Tk::event->W ->focusPrev; Tk::break(); } ); $mw -> bind('all','<Shift-Tab>', sub { $Tk::event->W ->focusNext; Tk::break(); } );
        Very nice! But, for me, Shift-Tab does not work, I have to specify Shift-ISO_Left_Tab :-(
Re: Tab Order for Widgets in HList
by kean (Sexton) on Oct 19, 2011 at 13:48 UTC
    This works fine with Entrys. But when there is a JComboBox in the middle it ends at the first JComboBox. The crazy thing is that Shift-Tab works with JComboBox....
    use strict; use warnings; use Tk; use Tk::HList; my $mw = MainWindow->new(); my $hlist = $mw->HList( -header => 0, -columns => 1 )->pack; $hlist->add(0); $hlist->itemCreate(0, 0, -itemtype => 'window', -widget => $hlist->Ent +ry(-text => "Text0") ); $hlist->add(1); $hlist->itemCreate(1, 0, -itemtype => 'window', -widget => $hlist->Ent +ry(-text => "Text1") ); $hlist->add(2); $hlist->itemCreate(2, 0, -itemtype => 'window', -widget => $hlist->Ent +ry(-text => "Text2") ); $hlist->add(3); $hlist->itemCreate(3, 0, -itemtype => 'window', -widget => $hlist->JCo +mboBox(-choices => ['Nein', 'Ja']) ); $hlist->add(4); $hlist->itemCreate(4, 0, -itemtype => 'window', -widget => $hlist->Ent +ry(-text => "Text4") ); $mw->bind('all','<Tab>', sub { $Tk::event->W ->focusPrev; Tk::break(); + } ); $mw->bind('all','<Shift-Tab>', sub { $Tk::event->W ->focusNext; Tk::br +eak(); } ); MainLoop;

      That is a bug in Tk::JDialog

      Test it without using override binding, and you'll see, with Tag, it goes backwards, but it cycles/loops through all items continually

      But if you use Shift+Tab it will stop on JDialog

      I surmise this is a bug in JDialog, but it could be a bug in HList or Tk... report upstream :)