📄 114.html
字号:
<HTML><TITLE>Overview of Tk: Enhancing Caps with Tab</TITLE><BODY BGCOLOR="#FFF0E0" VLINK="#0FBD0F" TEXT="#101000" LINK="#0F0FDD">
<A NAME="top"><H1>Enhancing Caps with Tab</H1></A>
<P> In this section, the Caps script is changed so that the <TT>.edit_button</TT> button
performs not one but two functions. The Tab key is used to switch between the
functions. This alters the Tab key from its default behavior.
<P> The default behavior of the Tab key is to switch the focus between those
widgets which are capable of taking the focus. There is no real need to
switch the focus in the Caps example. Although the button widgets can take
the focus – they show they have the focus by getting a black border – it is
not normally used when a mouse is available.
<P> This enhancement of the Caps example forces us to look at the <TT>bind</TT>
command. The <TT>bind</TT> command is needed to associate our own event handler with
the use of the Tab key.
<P> The string <TT>.edit_button</TT> names a button widget and a widget command.
All widget commands, that is to say all widget object action families, have a
<TT>configure</TT> action that can be used to change the option values. This
action can be applied to almost any option that can be set when the widget is
created. Here is the way to change the <TT>.edit_button</TT>'s <TT>-text</TT> and
<TT>-command</TT> options.
<PRE>
.edit_button configure -text Small \
-command { set Entry [string tolower $Entry] }
</PRE>
As you can see, the button's label is changed to "Small" and the associated
event handler is changed to a script that will convert all the letters
in <TT>Entry</TT> to lowercase.
<P> A similar use of the <TT>.edit_button</TT> widget command can change
the <TT>.edit_button</TT> button back to its original configuration.
<A NAME="prcdrsfrswtchngthdtbttnss">
<H3>Procedures for Switching the Edit Button's State</H3></A>
<P> The revised script needs a way to know which <TT>.edit_button configure</TT>
action to execute. There are various ways to accomplish this. The one used
is to keep a top-level variable, <TT>switchState</TT>, whose value is the name of
the procedure to execute the next time the <TT>.edit_button</TT> widget is to be
reconfigured. Part of what that procedure must do is change the value of
<TT>switchState</TT>.
<P> <STRONG>Remark</STRONG> <DL><DD> You may have noticed that <TT>switchState</TT> is not quite
consistent with my usual practice of starting variable names with uppercase
letters and procedure names with lowercase letters. This is because the
variable <TT>switchState</TT> exists to name a procedure. </DL>
<P> The two procedures for switching <TT>.edit_button</TT> configuration are
<TT>initForCaps</TT> and <TT>initForSmall</TT>. You can see them in Figure 11.4a.
<P> One difference between the root window shown in Figure
11.1b (The Caps example) and the root window shown in Figure 11.4a (The
enhanced Caps example) has nothing to do with the changes to the script. The
entry area in Figure 11.4a has a black border and shows a cursor. That
is not true in Figure 11.1b. The reason is that no focus is apparent in
Figure 11.1b whereas in Figure 11.4a, the entry widget has the focus.
<P><CENTER><TABLE BORDER>
<CAPTION><ADDR>Figure 11.4a: The enhanced caps example.</ADDR></CAPTION>
<TR ALIGN=center><TD><IMG SRC="F11x4a.JPG" tppabs="http://www.mapfree.com/sbf/tcl/book/select/Figs/F11x4a.JPG">
</TD></TR>
<TR><TD><PRE>proc initForCaps {} {
<P> global switchState
<P> .edit_button configure -text Caps \
<P> -command { set Entry [string toupper $Entry] }
<P> set switchState initForSmall
}
proc initForSmall {} {
<P> global switchState
<P> .edit_button configure -text Small \
<P> -command { set Entry [string tolower $Entry] }
<P> set switchState initForCaps
}
proc quit {} {
<P> global Entry switchState
<P> destroy .entry .edit_button .quit_button
<P> unset Entry switchState
<P> bind . <Key-Tab> {}
}
entry .entry -textvariable Entry
pack .entry
button .edit_button
pack .edit_button
button .quit_button -text Quit -command { quit }
pack .quit_button
initForCaps
bind . <Key-Tab> { $switchState; break } </PRE></TD></TR>
</TABLE></CENTER><P>
<P> All that remains to explain the revised script is to describe how <TT>bind</TT>
is used.
<A NAME="thbndcmmnd">
<H3>The Bind Command</H3></A>
<P> If you can accomplish what you need through Tk's widgets you should do so.
It is likely that your code will be less portable and have more errors when
you use the <TT>bind</TT> command. Still, there are times when the <TT>bind</TT>
command is very helpful.
<P> What <TT>bind</TT> does is arrange for an event handler to be triggered by a
particular kind of event involving some set of widgets. Usually the
event is a user event. Samples are:
<PRE>
<Key-Tab>
<Control-key-a>
</PRE>
Event handlers are the same kind of scripts passed as values to the
<TT>-command</TT> option. Windows can be identified with their names.
<P> Returning to the enhanced Caps example, here is a command line that binds a
switch of states to the Tab key.
<PRE>
bind all <Key-Tab> { $switchState; break }
</PRE>
The binding is effective when any widget in the application has the focus.
<P> If you wanted to bind the <TT>exit</TT> action to the user
event of a user pressing the letter "c" with the control (or Ctl) key held
down, you might do it this way:
<PRE>
bind all <Control-Key-c> exit
</PRE>
But, if for some reason you wanted the binding only to apply over
a button widget named <TT>.quit_button</TT>, you would write
<PRE>
bind .quit_button <Control-Key-c> exit
</PRE>
<P> Because bindings may apply to many widgets, any one widget may be involved
with several bindings to the same event. <CITE>The order in which these
bindings fire is important.</CITE> For one reason, if there is a <TT>break</TT> command
in an event handler, then any other bindings to the same event which may be
ready to fire will be ignored. Sorting out what happens in such circumstances
is complicated and the discussion is left until
<A HREF="NotHere.html" tppabs="http://www.mapfree.com/sbf/tcl/book/select/Html/NotHere.html">Bindings</A> below. For now,
here is an exercise to get you started thinking about what is going on.
<P><A NAME="11.4a">
<STRONG>Exercise 11.4a</STRONG> </A><DL><DD>
Add the following commands to Script S11.1a.
<PRE>
bind .quit_button <Motion> { break }
bind . <Motion> { puts {That tickles!}}
</PRE>
Because of the use of <TT>puts</TT>, this script needs to be executed
interactively. Describe the effect.
<P>
<A HREF="11.7.html#Sol11.4a" tppabs="http://www.mapfree.com/sbf/tcl/book/select/Html/11.7.html#Sol11.4a">Solution</A></DL>
<P> <P><A NAME="11.4b">
<STRONG>Exercise 11.4b</STRONG> </A><DL><DD>
Start the <TT>wish??</TT> interpreter and type some
bindings of control keys to simple event handlers directly into the command
window. Immediately after you have executed a <TT>bind</TT> command you can test
the effect in the root window.
<P> One possible event handler for this test is
<PRE>
{ puts "Lookatthat"; break }
</PRE>
though with the empty root window you will not need the break. The <TT>puts</TT>
command does the same thing it does in Tcl – it prints in the command window.
<P>
<A HREF="11.7.html#Sol11.4b" tppabs="http://www.mapfree.com/sbf/tcl/book/select/Html/11.7.html#Sol11.4b">Solution</A></DL>
<P> When you assign an empty string as the event handler to a binding, you
are clearing that binding. For the enhanced Caps example this is done in
the quit procedure where you will find this line:
<PRE>
bind . <Key-Tab> {}
</PRE>
<A NAME="pttngttgthr">
<H3>Putting It Together</H3></A>
<P> The complete enhanced Caps example is shown in Figure 11.4a. Pretty
much everything has been explained. The default values for <TT>-text</TT> and
<TT>-command</TT> are not changed when the <TT>.edit_button</TT> widget is created.
This is pure laziness. They do not need to be set at widget creation time
because they are set by the <TT>initForCaps</TT> command line that also
initializes the <TT>switchState</TT> variable.
<P> <P><A NAME="11.4c">
<STRONG>Exercise 11.4c</STRONG> </A><DL><DD>
<P> What would be the effect of moving the <TT>initForCaps</TT> command line
to just before the <TT>entry ...</TT> command line? Explain.
<P> <P>
<A HREF="11.7.html#Sol11.4c" tppabs="http://www.mapfree.com/sbf/tcl/book/select/Html/11.7.html#Sol11.4c">Solution</A></DL>
<P> <P><A NAME="11.4d">
<STRONG>Exercise 11.4d</STRONG> </A><DL><DD>
<P> What would be the effect of moving the last command line to the beginning
of the script? Explain. <P>
<A HREF="11.7.html#Sol11.4d" tppabs="http://www.mapfree.com/sbf/tcl/book/select/Html/11.7.html#Sol11.4d">Solution</A></DL>
<!-- Linkbar -->
<P><CENTER><FONT SIZE=2><NOBR>
<STRONG>From</STRONG>
<A HREF="javascript:if(confirm('http://www.mapfree.com/sbf/tcl/book/home.html \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://www.mapfree.com/sbf/tcl/book/home.html'" tppabs="http://www.mapfree.com/sbf/tcl/book/home.html">Tcl/Tk For Programmers</A><WBR>
<STRONG>Previous</STRONG>
<A HREF="11.3.html" tppabs="http://www.mapfree.com/sbf/tcl/book/select/Html/11.3.html">section</A><WBR>
<STRONG>Next</STRONG>
<A HREF="11.5.html" tppabs="http://www.mapfree.com/sbf/tcl/book/select/Html/11.5.html">section</A><WBR>
<STRONG>All</STRONG>
<A HREF="11.html" tppabs="http://www.mapfree.com/sbf/tcl/book/select/Html/11.html">sections</A><WBR>
<STRONG>Author</STRONG>
<A HREF="javascript:if(confirm('http://www.mapfree.com/mp/jaz/home.html \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://www.mapfree.com/mp/jaz/home.html'" tppabs="http://www.mapfree.com/mp/jaz/home.html">J. A. Zimmer</A><WBR>
<STRONG>Copyright</STRONG>
<A HREF="copyright.html" tppabs="http://www.mapfree.com/sbf/tcl/book/select/Html/copyright.html">Notice</A><WBR>
<P>
<I>Jun 17, 1998</I>
</NOBR></FONT></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -