old-www/HOWTO/Scripting-GUI-TclTk/basics.html

455 lines
10 KiB
HTML

<HTML
><HEAD
><TITLE
>Tcl and Tk Basics</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.7"><LINK
REL="HOME"
TITLE="Scripting Graphical Commands with Tcl/Tk Mini-HOWTO"
HREF="index.html"><LINK
REL="PREVIOUS"
TITLE="Introduction to Tcl and Tk"
HREF="intro.html"><LINK
REL="NEXT"
TITLE="Adding Features"
HREF="advanced.html"></HEAD
><BODY
CLASS="sect1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>Scripting Graphical Commands with Tcl/Tk Mini-HOWTO</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="intro.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
></TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="advanced.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="sect1"
><H1
CLASS="sect1"
><A
NAME="basics"
></A
>3. Tcl and Tk Basics</H1
><P
>&#13;Tcl is built up from commands which act on data, and which accept a number of options which specify how each command is executed. Each command consists of the name of the command followed by one or more words separated by whitespace. Because Tcl is interpreted, it can be run interactively through its shell command, <B
CLASS="command"
>tclsh</B
>, or non-interactively as a script. When Tcl is run interactively, the system responds to each command that is entered as illustrated in the following example. You can experiment with tclsh by simply opening a terminal and entering the command <B
CLASS="command"
>tclsh</B
>.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;$ tclsh
% set a 35
35
% expr 35 * $a
1225
% puts "35 * a is: [ expr 35 * $a ]"
35 * a is: 1225
% exit
$
</PRE
></FONT
></TD
></TR
></TABLE
><P
>&#13;The previous example illustrates several aspects of the Tcl language. The first line, <B
CLASS="command"
>set a 35</B
> assigns 35 to the variable <B
CLASS="command"
>a</B
> using the <B
CLASS="command"
>set</B
> command. The second line evaluates the result of 35 times the value of <B
CLASS="command"
>a</B
> using the <B
CLASS="command"
>expr</B
> command. Note that Tcl, like Perl and Bash requires the use of the dollar operator to get the value of a variable. The open brackets around the expression <B
CLASS="command"
>[ expr 35 * $a ]</B
> instruct the interpreter to perform a command substitution on the expression, adds it to the rest of the string and uses the puts command to print the string to Tcl's default output channel, standard output.
</P
><P
>&#13;Tcl's windowing shell, <B
CLASS="command"
>Wish</B
>, is an interpreter that reads commands from standard input or from file, and interprets them using the Tcl language, and builds graphical components from the Tk toolkit. Like the <B
CLASS="command"
>tclsh</B
>, it can be run interactively.
</P
><P
>&#13;To invoke Wish interactively, start X on your system, open a terminal, and type <B
CLASS="command"
>wish</B
> at the command prompt. If your environment is set up properly, this will launch an empty root window and start the windowing shell in your terminal. The following example is a two-line script that is one of the simplest programs that can be created with <B
CLASS="command"
>wish</B
>:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;$ wish
% button .submit -text "Click Me" -command { puts "\nHello World" }
.submit
% pack .submit
</PRE
></FONT
></TD
></TR
></TABLE
><P
>&#13;Let's break down these two lines of code:
</P
><P
>&#13;<B
CLASS="command"
>button .submit -text "Click Me" -command { puts "\nHello World" }</B
>:
</P
><P
>&#13;The <B
CLASS="command"
>button</B
> command enables you to create and manipulate the Tk button widget. As with all Tk widgets, the syntax is <B
CLASS="command"
>button</B
> <B
CLASS="command"
>.name</B
> <B
CLASS="command"
>[-option value]</B
> <B
CLASS="command"
>[-option value] ...</B
>. The curly braces surrounding the <B
CLASS="command"
>puts</B
> command allow you to nest the text string, "Hello World", inside of the command without performing any variable substitutions. Other basic widgets include the following: label, checkbutton, radiobutton, command, separator, entry, and frame. Click the button a few times to verify that it works.
</P
><P
>&#13;<B
CLASS="command"
>pack .submit</B
>
</P
><P
>&#13;The <B
CLASS="command"
>pack</B
> command tells the Tk packer geometry manager to pack the window name as a slave of the master window <B
CLASS="command"
>.</B
> which is always referred to by the character <B
CLASS="command"
>.</B
>. As with the other Tk widget commands we will see, the syntax is <B
CLASS="command"
>pack .name [-option value] [-option value]</B
>.
</P
><P
>&#13;While the previous example was very simple, more advanced examples are nearly as easy to build. Have a look at the following script which creates a simple graphical front end for apachectl ( please note, this example is intended to be run as a script rather than interactively from the shell. You will need to set the permissions of the script as executable and run this script as a user with privileges to start and stop apache ):
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;#!/usr/bin/wish
set apachectl "/usr/local/apache/bin/apachectl"
global apachectl
proc start {} {
global apachectl
exec $apachectl start &#38;
}
proc stop {} {
global apachectl
exec $apachectl stop &#38;
}
proc restart {} {
global apachectl
exec $apachectl restart &#38;
}
proc screen {} {
frame .top -borderwidth 10
pack .top -fill x
button .top.start -text "Start" -command start
button t.op.stop -text "Stop" -command stop
button .top.restart -text "Restart" -command restart
pack .top.start .top.stop .top.restart -side left -padx 0p -pady 0
}
screen
</PRE
></FONT
></TD
></TR
></TABLE
><P
>&#13;This script introduces a few new concepts. Let's look at some of them line by line:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;set apachectl "/usr/local/apache/bin/apachectl"
global apachectl
</PRE
></FONT
></TD
></TR
></TABLE
><P
>&#13;As we saw earlier, the <B
CLASS="command"
>set</B
> command is used to assign a value to a variable. As with the previous examples, the syntax is simple: <B
CLASS="command"
>set variable_name value</B
>. In order to make the variable available to the Tcl procedures that we are creating in this program, we need to import the apachectl variable into each procedure. This is accomplished using the <B
CLASS="command"
>global</B
> command which adds a named variable to the local namespace of a given procedure. The <B
CLASS="command"
>global</B
> command accepts one or more variables as arguments and assigns the named variables to each procedure used in the program. Global is also used to export variables that are declared within a procedure's local namespace.
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>&#13;proc start {} {
global apachectl
exec $apachectl start &#38;
}
</PRE
></FONT
></TD
></TR
></TABLE
><P
>&#13;Procedures in Tcl are created with the <B
CLASS="command"
>proc</B
> command. The <B
CLASS="command"
>proc</B
> command takes the following form: <B
CLASS="command"
>proc name {args} {body}</B
> where name is the name of the procedure. Args are the formal arguments accepted by the procedure, and body is the main code of the procedure. Procedures are executed the same way that any other command is executed in Tcl.
</P
><P
>&#13;The script we are currently working with consists of 4 procedures. The first 3 ( start, stop, restart ), simply import the apachectl variable into the local namespace and execute the basic apachectl commands as background processes while the 4th procedure, "<B
CLASS="command"
>screen</B
>", uses the packer to build the basic screen and call each of the functions.
</P
><P
>&#13;Let's have a closer look at the <B
CLASS="command"
>screen</B
> procedure:
</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><FONT
COLOR="#000000"
><PRE
CLASS="screen"
>
proc screen {} {
frame .top -borderwidth 10
pack .top -fill x
button .top.start -text "Start" -command start
button .top.stop -text "Stop" -command stop
button .top.restart -text "Restart" -command restart
pack .top.start .top.stop .top.restart -side left -padx 0p -pady 0
}
</PRE
></FONT
></TD
></TR
></TABLE
><P
>&#13;The <B
CLASS="command"
>screen</B
> procedure begins by using the <B
CLASS="command"
>frame</B
> command to construct the basic frame that will contain the buttons specified further down in the procedure. As this example illustrates, slave widgets are specified by prepending them with the name of their master followed by a ".". The master must already be packed before the slave can use them, so we pack the frame .top before specifying the <B
CLASS="command"
>button</B
> command and tell it to fill along the x axis.
</P
><P
>&#13;Last, we use the <B
CLASS="command"
>button</B
> command to create 3 buttons as slaves to <B
CLASS="command"
>.top</B
>, passing in the appropriate procedure to execute when the button is pressed, and adding a text label using the <B
CLASS="command"
>-command</B
> and <B
CLASS="command"
>-text</B
> arguments, respectively.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="intro.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="index.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="advanced.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>Introduction to Tcl and Tk</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
>&nbsp;</TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Adding Features</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>