Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Handling TABs

120 views
Skip to first unread message

Bernie Cosell

unread,
Oct 28, 2007, 5:20:23 PM10/28/07
to
Much thanks for the clue-train stop on the getOpenFile-before-MainLoop
silliness. I'd still like my pgm to ask for the DB file first, but
instead of that kludge, I'll just have a little frame with an Entry widget
and getOpenFile bound to a "browse" button [should be adequate: FileSelect
has the same problem if needing to be invoked as a method instead of being
able to be PACKed as a widget].

That has gotten me thinking about another thing from my HTML/CGI days that
I don't exactly understand how to do in TK:

TAB order: Mastering Perk/Tk just says that "The order in which the focus
moves around matches the order that you packed the widgets...". that's
pretty clumsy. Is there some way [ala html's Tabindex] to explicitly
establish the tab-order of the widgets?

I was reading about -takefocus and Mast P/TK just says "Note: this
interpretation of the option is defined entirely by the Callbacks that
implement traversal: the widget implementations ignore the option entirely,
so you can change its meaning if you redefine the keyboard traversal
scripts."

Anyone tried to do something like that? I'm guessing that by the
'callback' they're referring to having <Key-Tab> 'bind'ed in some global
way to a callback that moves the focus from one window to another, but I'm
not sure how to intercept it and try to make it do what I want. [seems
like it'd be complicated... it'd be nice if the 'traversal scripts'
supported a 'TabOrder' option and when you hit TAB it moved focus to the
widget with the next-larger TabOrder value [among the widgets it would
consider: active, being displayed, etc]]

/Bernie\
--
Bernie Cosell Fantasy Farm Fibers
ber...@fantasyfarm.com Pearisburg, VA
--> Too many people, too few sheep <--

zentara

unread,
Oct 29, 2007, 9:27:34 AM10/29/07
to
On Sun, 28 Oct 2007 17:20:23 -0400, Bernie Cosell
<ber...@fantasyfarm.com> wrote:

>TAB order: Mastering Perk/Tk just says that "The order in which the focus
>moves around matches the order that you packed the widgets...". that's
>pretty clumsy. Is there some way [ala html's Tabindex] to explicitly
>establish the tab-order of the widgets?

>Anyone tried to do something like that? I'm guessing that by the


>'callback' they're referring to having <Key-Tab> 'bind'ed in some global
>way to a callback that moves the focus from one window to another, but I'm
>not sure how to intercept it and try to make it do what I want. [seems
>like it'd be complicated... it'd be nice if the 'traversal scripts'
>supported a 'TabOrder' option and when you hit TAB it moved focus to the
>widget with the next-larger TabOrder value [among the widgets it would
>consider: active, being displayed, etc]]
>
> /Bernie\

Here is a script posted before, that SORT of addresses your issue.
The problem is it works for any key BUT Tab, :-)

Tab order is built-in to MainWindow widgets, so you may need to
subclass it to remove the built-in default order.
Read the source for MainWindow.pm and you will see in the InitBindings
sub, where Tabs are predefined.

Try hitting escape, or space, with this script and it works, but
Tab won't change.

Maybe someone else may know the right technique, or a quick
way to subclass the MainWindow.

#!/usr/bin/perl
use Tk;
use strict;
use warnings;

#changes focus on ANY key BUT tab

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;
my $boo = $otherwin->Entry->pack;
my $baa = $otherwin->Entry->pack;

&defineOrder($foo,$baa,$bar,$boo,$baz);
}

sub defineOrder
{
my $widget;
for (my $i=0; defined( $_[$i+1] ); $i++)
{

# $_[$i]->bind('<Tab>', [\&focus, $_[$i+1]]);
$_[$i]->bind('<Any-KeyPress>', [\&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();

__END__

zentara

--
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html

Bernie Cosell

unread,
Oct 30, 2007, 7:47:59 AM10/30/07
to
zentara <zen...@highstream.net> wrote:

} On Sun, 28 Oct 2007 17:20:23 -0400, Bernie Cosell
} <ber...@fantasyfarm.com> wrote:
}
} >TAB order: Mastering Perk/Tk just says that "The order in which the focus
} >moves around matches the order that you packed the widgets...". that's
} >pretty clumsy. Is there some way [ala html's Tabindex] to explicitly
} >establish the tab-order of the widgets?

} Here is a script posted before, that SORT of addresses your issue.


} The problem is it works for any key BUT Tab, :-)
}
} Tab order is built-in to MainWindow widgets, so you may need to
} subclass it to remove the built-in default order.
} Read the source for MainWindow.pm and you will see in the InitBindings
} sub, where Tabs are predefined.

Thanks... and I guess the basic answer is "you really can't set the tab
order to be what you want". [messing down in the bowels of MainWindow.pm
and all of that is really too much hassle for something like this]. It is
a bit funny that Tk does so many things very slickly but some other
simple-seeming things verge on the impossible....

Ch Lamprecht

unread,
Oct 30, 2007, 9:14:25 AM10/30/07
to
Bernie Cosell schrieb:

Hi,
I don't see any problems, using the most straightforward approach I can think of
(binding <Tab> for $mw):

use strict;
use warnings;

use Tk;

my $mw = MainWindow->new();

my $foo = $mw->Entry->pack;
my $baz = $mw->Entry->pack;
my $boo = $mw->Entry->pack;


my %after = ($foo => $boo,
$boo => $baz,
$baz => $foo,
);

$mw -> bind('all','<Tab>',sub{($after{$_[0]})->focus;Tk::break()});

MainLoop();

Christoph

--
use Tk;use Tk::GraphItems;$c=tkinit->Canvas->pack;push@i,Tk::GraphItems->
TextBox(text=>$_,canvas=>$c,x=>$x+=70,y=>100)for(Just=>another=>Perl=>Hacker);
Tk::GraphItems->Connector(source=>$i[$_],target=>$i[$_+1])for(0..2);
$c->repeat(30,sub{$_->move(0,4*cos($d+=3.16))for(@i)});MainLoop

0 new messages