Liz Potterton
The Tcl/Tk online documentation is excellent for quick reference.
You can use tclsh in command line mode to try stuff.
puts outputs a text string to the terminal - note use of double quotes (always in Tcl).
or, using Tk graphics commands to create a widget:
% label .l -text "Hello World" -
% pack .l
% bind .l <Button> {puts "Goodbye"; exit}
The label command creates a label widget called .l (which is a child
of the default window called just . (dot)).
The pack command 'packs' this widget into the window.
The bind command attaches a command to the label widget which is activated
if the mouse button is clicked. The command script is enclosed in
curly brackets and outputs a brief message and then exits from wish.
CreateLine line \
label "Number of refinement
cycles" \
widget NCYCLES
The line argument returns the id for the line which might be something like:
.w_demo.main.canvas.contents.param_1.body.l9
The dots serve like backslash in file path names and
.w_demo | the name of the demo window |
main.canvas.contents | a layer which is necessary to set up the scrollable frame |
param_1 | the id for the first generic folder (i.e. not protocol or file) in the window |
body | refers to the body of the folder, rather than the title line |
l9 | the id of the line |
Once you know the id of the line it is possible to do some direct customisation
of the widgets or to create novel widgets. This is not recommended
as a regular thing.
proc max { arg1 arg2 } {
if { $arg1 > $arg2 } {
return
$arg1
} else {
return
$arg2
}
}
The proc command defines
a procedure - this command has three arguments:
In this example the procedure is called max and has two arguments,
arg1 and arg2. In the body of the procedure is a simple conditional
statement to return the larger of the two arguments.
Note:
And how to use the procedure..
set x [max 3 4]
puts "x = $x"
This is using the set command to give a value to the variable 'x' which is the result from the command max.
set | set a variable parameter |
string | variety of string manipulations |
append | append text to a variable |
regexp | regular expression matching |
regsub | using regular expression to modify a string |
There are two forms of collective variables: lists and arrays.
set name_list [list Pete Martyn Charles Alun]
or (not recommended) by enclosing in curly brackets
set name_list {Pete Martyn Charles Alun}
Text string can be treated as a list with each word as a list item (but beware can 'lose' spaces).
Commands which manipulate lists
list | Create a list |
lappend | Append items to end of a list |
linsert | Insert items in a list |
lreplace | Replace items in a list |
concat | Concatenate lists |
lindex | Extract one item from a list |
lsearch | Search a list for an item |
lsort | Sort a list |
llength | Return the length of a list |
set demo(NCYCLES) 5
set demo(RESOLUTION_MAX) 3.0
Here the array is called demo and the elements of the array are called
NCYCLES and RESOLUTION_MAX
Note that the array elements are not called 1,2,3.. (Fortran) or 0,1,2,3..
(C).
In CCP4i there is one array associated with each task interface.
The name of the array is decided by the core CCP4i, which ensures a
unique name (usually has the same name as the task) and passes the name
of the array to the procedures in the taskname.tcl file which then
look like this:
proc demo_task_window { arrayname } {
upvar #0 $arrayname array
--snipped--
}
The procedure demo_task_window is the main procedure defining the demo task. The name of the array is passed in in the variable arrayname. The command upvar is used to make the contents of the array visible in the context of this procedure and the variables are accessed as array(NCYCLES) or array(RESOLUTION_MAX).
Generally the task window widgets are passive - they do not have any
actions attached but it is possible to attach commands to a button and
also to change the buttons at the bottom of the task window.
Variables which are used in extending frames and toggle frames (for example the variables CHAIN, RES1 and RES2 used in the definition of 'Protein Ranges to Refine' in the demo task):
The names of the variables used in the interface to define two residue ranges (by a chain id and the first and last residue id) are:
demo(CHAIN,1) demo(FIRST_RES,1) demo(LAST_RES,1)
demo(CHAIN,2) demo(FIRST_RES,2) demo(LAST_RES,2)
These are given an index number separated from the variable name by a comma. To Tcl the comma is just another character in the variable name. Only CCP4i understands the comma to be special character.
In the def files, which set initial values for variables there is:
CHAIN1,0
_chain_id
""
FIRST_RES,0
_res_id
""
LAST_RES,0
_res_id
""
The variable with the index value 0 is never accessible from the task window but is used as the initialiser for the actual variables which are created automatically.
There are cases of double nested extending frames, for example in heavy atom refinement the top frame defines isomorphous derivatives and the nested frame defines the heavy atoms within each derivative. The variables to define the heavy atom coordinates might be:
For the first derivative the coordinates of three heavy atoms:
array(HA_X,1_1) array(HA_Y,1_1) array(HA_Z,1_1)
array(HA_X,1_2) array(HA_Y,1_2) array(HA_Z,1_2)
array(HA_X,1_3) array(HA_Y,1_3) array(HA_Z,1_3)
and for the second derivative the coordinates of two heavy atoms:
array(HA_X,2_1) array(HA_Y,2_1) array(HA_Z,2_1)
array(HA_X,2_2) array(HA_Y,2_2) array(HA_Z,2_2)
Note that an underscore is used as a separator (why not a comma again?
doh!).