Search code examples
perluser-interfacewidgetperltk

Perl tk - tab between entry widgets


I have a very simple GUI which interacts with postgresql database. The mainframe is split into 4 quadrants with each quadrant having 4 Entry Widgets. Here is an example code of one quadrant

my $f_blue = $bottom_half->Frame(-bg=>'BLUE')-> pack(-side=>'left', -expand=>1, -fill=>'both');
$f_blue->Label(-text=>'BLUE', -bg=>'blue', -fg=>'white')->pack(-side=>'top');

my $blue_table = $f_blue->Table(-rows => 3,
                   -columns => 3,
                   -fixedrows => 1,
                   -fixedcolumns => 1,
                   -scrollbars => 'oo',
                   -relief => 'raised') -> pack(-side => 'top', -expand => 1, -fill=>'both');

$blue_table -> put(1,1,
          $blue_table->Label(-text => 'Cs-137:'));

my $t_blue_cs137 = $blue_table->Entry(-selectbackground=>"blueviolet");
$blue_table -> put(1,2,$t_blue_cs137);

$blue_table -> put(1,3,
          $blue_table->Label(-text => 'MBq'));



$blue_table -> put(2,1,
          $blue_table->Label(-text => 'Tc-99m:'));
my $t_blue_tc99m = $blue_table->Entry(-selectbackground=>"blueviolet");
$blue_table -> put(2,2,$t_blue_tc99m);
$blue_table -> put(2,3,
          $blue_table->Label(-text => 'MBq:'));

$blue_table -> put(3,1,
          $blue_table->Label(-text => 'Tl-201:'));
my $t_blue_tl201 = $blue_table->Entry(-selectbackground=>"blueviolet");
$blue_table -> put(3,2,$t_blue_tl201);
$blue_table -> put(3,3,
          $blue_table->Label(-text => 'MBq:'));

When entering data using the GUI I am unable to tab to skip to the next entry. Is there a way of setting key bindings so I can loop to set

`$t_blue_cs137` to be active
 PRESS TAB
`$t_blue_tc99m` NOW ACTIVE
PRESS TAB
`$t_blue_tl201` NOW ACTIVE
PRESS TAB
Do the same with the next quadrant
`$t_red_cs137`  in frame $f_red NOW ACTIVE

Is there a way to do this in perlTK

I have tried the following

$f_blue->bindtags( [ ($f_blue->bindtags)[$t_blue_cs137,$t_blue_tc99m,$t_blue_tl201] ] );
# fix the bindtags order so that widget events are
# processed before class events
$f_blue->bind("<Tab>", sub { $f_blue->focusNext; Tk->break; });

However, this only lets me tab between each subframe and the buttons in the GUI


Solution

  • Define

    -takefocus => 0,
    

    in the Table configuration.

    By default, -takefocus is set to a true value, which is causing the FocusChildren method to return an empty list, and this in turn means that the focus is never given to the table's child widgets. Not the best default, but this behavior was introduced in Tk 402.001 and probably now it's too late to change. But maybe there should be a paragraph in the documentation describing this trap...