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

Accelerators (key bindings) and tabs

6 views
Skip to first unread message

Twylite

unread,
Sep 14, 2007, 6:24:08 AM9/14/07
to
Hi,

We have an application with multiple pages/tabs (PageControl,
TabControl, Notebook, call it what you may). On some of those tabs we
have buttons and labels that have accelerator indicators. To make
those accelerators work one normally binds the key combination to the
toplevel -- but with multiple pages/tabs this allows key combinations
to invoke actions on widgets that aren't on the displayed tab. How do
I resolve this?

We use our own page switching widget but ttk::notebook has the same
behaviour for the purposes of this discussion; here's an example:

ttk::notebook .nb
.nb add [frame .nb.f1] -text "First tab"
button .nb.f1.b -text "Hello" -underline 0 -command { puts
"Hello" }
bind . <Alt-Key-h> [list .nb.f1.b invoke]
pack .nb.f1.b
.nb add [frame .nb.f2] -text "Second tab"
.nb select .nb.f2
ttk::notebook::enableTraversal .nb
pack .nb

While viewing the second tab (the button is not visible) press Alt-H -
the string "Hello" shows on the console.

Now you can't bind to the notebook .nb, because the event will only be
delivered there if the notebook itself has the focus (i.e. you can see
the focus drawn on the tabs). If the button has the focus the event
doesn't get delivered to .nb.

You can't bind to the frame .nb.f1because it never has focus (unless
you configure it with -takefocus 1, in which case it only gets events
when it has focus, not one of its parent or child widgets).

Right now I can only think of a few possible solutions:

1. Delete the bindings for a particular tab when you switch off it,
and add the bindings for the tab you are switching too. That's a lot
of admin and not at all elegant.

2. Bind to a class Page.(frame), e.g. Page.nb.f1, and use bindtags to
add the class for the visible page/tab to the tag list for the
toplevel (.); then just update the bindtags for . when you switch
pages.

Any thoughts? Surely someone has encountered this problem before?

Regards,
Twylite

Joe English

unread,
Sep 21, 2007, 2:49:42 PM9/21/07
to
Twylite wrote:
>
>We have an application with multiple pages/tabs (PageControl,
>TabControl, Notebook, call it what you may). On some of those tabs we
>have buttons and labels that have accelerator indicators. To make
>those accelerators work one normally binds the key combination to the
>toplevel -- but with multiple pages/tabs this allows key combinations
>to invoke actions on widgets that aren't on the displayed tab. How do
>I resolve this?


The "keynav" package in Tile (undocumented except for comments
in the source file, but otherwise supported) can help with this.

See here:

http://tktable.cvs.sourceforge.net/*checkout*/tktable/tile/library/keynav.tcl?revision=1.8

Basic usage is:

keynav::enableMnemonics $top

That adds an <Alt-KeyPress> binding to the specified toplevel
that will enable mnemonic activation for all widgets in that toplevel.
You usually don't need to do anything else other than setting
the "-underline" option on individual widgets.

Mnemonic activation works for any viewable widget that has
"-text" and "-underline" options and a binding for the <<Invoke>>
virtual event. (The keynav package adds <<Invoke>> bindings for
Button, Checkbutton, and Radiobutton widgets; tile widgets have
support built in.)

[keynav::enableMnemonics] doesn't work for ttk::notebook widgets --
the widget doesn't have "-text" and "-underline" options, only the tabs do --
but it's compatible with [ttk::notebook::enableTraversal].
In particular, it will only invoke widgets on the current tab,
as desired.


--Joe English

0 new messages