I have had similar problems, except that I usually wanted to allow tabs to be inserted into the Text widget.
Interestingly, Shift-<Tab> still reverses the sequence according to Tk's builtin order, including to get out of a Text widget.
The most elegant solution would be to adjust the stacking order so that Tk's builtin focus order matches what you want, see "focusNext" in Tk::focus and "raise" in Tk::Widget. This approach also preserves the "tab-in" behavior of focusing the first widget when the user presses <Tab> and no widget has the focus within the window.
Finding a solution to this, producing <Tab> key behavior not unlike that in the browser I am using to compose this reply, required some time with the Tk manual and was quite enlightening along the way. I recommend installing Tk::Pod if you do not already have it — tkpod makes navigating the sprawling Tk manual easy. In the below code, I have also added a binding that exits the program upon typing Control-Q for convenience in testing and initialized the Text widget to contain a dump of its own bindings, which revealed a class binding for <Tab> that inserts a tab character. This is overridden on line 17 to instead do nothing, allowing the default global binding for focusNext to work. Removing the binding also works, but leaves the default InsertKeypress binding to run, which inserts a tab, then the global binding changes focus. Maddening at first...
use strict;
use warnings;
use Tk;
my $mw = MainWindow->new();
my $entry1 = $mw->Entry()->pack();
my $entry2 = $mw->Entry()->pack();
my $entry3 = $mw->Entry()->pack();
my $text = $mw->Scrolled('Text')->pack();
my @order = ($entry1 , $entry3, $entry2, $text);
for (my $i = 1; $i < @order; $i++) { $order[$i]->raise($order[$i-1]) }
$mw->bind('<Control-q>', sub {exit 0});
$text->Subwidget('xscrollbar')->configure(-takefocus => 0);
$text->Subwidget('yscrollbar')->configure(-takefocus => 0);
$text->Subwidget('scrolled')->bind('Tk::Text','<Tab>', 'NoOp');
$text->insert('1.0', join('',$text->Subwidget('scrolled')->bindDump));
$mw->MainLoop();
exit(0);
Dumping the default bindings also reveals that <Control-Tab> executes focusNext even on a Tk::Text widget. |