# Tcl Programming/Tk
### Introduction

The Tk (Tool Kit) is the most popular Tcl extension for designing graphical user interfaces (GUI) on Macintosh, Unix/Linux, or Windows operating systems.
With little effort, it allows to put together useful
* windows (forms, as some call them) consisting of
* widgets, which are managed by
* geometry managers. Also, you can easily define
* bindings of mouse or keyboard events to trigger the actions you want.

#### Example: calculator

Here is a very simple, complete Tcl/Tk script that implements a calculator:
It creates an entry widget named .e, into which you can type from the keyboard, with an associated variable e (which will mirror the entry's content), and manages it with pack.
One binding is defined: if with keyboard focus on .e, the <Return> key is hit, then
* all division operators (/) in the variable e are mapped to "*1./" (this forces floating point division),
* the resulting string is fed to expr to evaluate it as an arithmetic/logic expression
* as there may be errors in the user input, the expr call is wrapped into a catch which assigns either the result of expr, or the error message if one occurred, into the variable res
* the result of the last evaluation is cleared by deleting everything after =
* finally, an equal sign and the value of the res variable are appended to e, making input and result immediately visible in the entry.

#### Example: a tiny IRC client

As before in the Tcl section, here's a working little script again: a client for IRC (Internet Relay Chat) in 38 lines of code, that features a text and an entry widget:
The last line is a quick debugging helper: if you modified the script in the editor, save to disk, then hit <Escape> in the app to start it anew.

### Widgets

Widgets are GUI objects that, when mapped by a geometry manager, correspond to a rectangular area on the screen, with different properties and capabilities.
Widgets are named with path names, somewhat resembling file system path names, except that the separator for widgets is a period ".". For example, .foo.bar is a child of foo which is a child of "." Parent-child relation occurs typically with containers, e.g. toplevel, frame, canvas, text. The name parts (i.e. between the dots) can be almost any string that does not contain "." of course, or starts with a Capital Letter (this is because widget class names with capital initial have a special meaning, they denote class-wide options).
If you have a proc that takes a parent widget w and adds children, it may be important to distinguish whether w is "." or another - because you can't concatenate a child widget name directly to "." - $w.kid will make an invalid name if $w == ".". Here's how to avoid this:
Widgets are created by a command named after their class, which then takes the path name (requiring that parent widgets have to exist by that time) and any number of -key value options that make up the original configuration, e.g.
After creation, communication with the widget goes via a created command that corresponds to its name. For instance, the configuration options can be queried
or changed
Some "methods" like cget, configure are generic to all widget classes, others are specific to one or a few. For instance, both text and entry accept the insert method. See the manual pages for all the details.
Widgets appear on screen only after they have been given to a geometry manager (see more below). Example:
As widget creation commands return the pathname, these two steps can also be nested like
The destroy command deletes a widget and all of its child widgets, if present:
The following sub-chapters describe the widgets available in Tk.

#### button

With text and/or image, calls a configurable command when clicked. Example:

#### canvas

Scrollable graphic surface for line, rectangle, polygon, oval, and text items, as well as bitmaps and photo images and whole embedded windows. See for example "A tiny drawing program" below. Example:
Pan a canvas (scroll it inside its window with middle mouse-button held down) by inheriting the text widget bindings:

#### entry

One-line editable text field, horizontally scrollable (see example above). You can specify a validation function to constrain what is entered. Example:

#### frame

Container for several widgets, often used with pack, or for wrapping "megawidgets"

#### label

One- or multiline field for text display, can be tied to a text variable to update when that variable changes. Linebreaks are specified by \n in the text to be displayed.

#### labelframe

A container similar to a frame, decorated with a thin rectangle around, and a label at top-left position. Example (a tiny radio band selector):

#### listbox

Multiline display of a list, scrollable. Single or multiple items can be selected with the mouse.

#### menu

To add a menu to a GUI application, take steps of three kinds:
* Create the toplevel horizontal menu (needed only once):
* For each item in the top menu, create a cascaded submenu, e.g.
* For each entry in a submenu, add it like this:
As these commands are a bit verbose, one can wrap them into a little helper:
Demo example - now menu items can be created in a much clearer way:

#### radiobutton

A button with a selector field which can be on or off, and a label. Clicking the selector field with the mouse changes the value of an associated global variable. Typically, multiple radiobuttons are tied to the same variable. For examples, see labelframe above.

#### scrollbar

Horizontal or vertical scrollbars (vertical being the default, for horizontal specify: -orientation horizontal, or -ori hori if you like it short) can be tied to canvas, entry, listbox or text widgets. The interaction between a scrollbar and its scrolled widget goes with callbacks, in which one notifies the other:
* scrollbar to widget: xview or yview method
* widget to scrollbar: set method
Arguments to these methods will be automatically added when the callbacks are invoked.
For example, here's how to connect a text widget with a vertical scrollbar:
With most widgets, scrollbars adjust automatically to the widget's contents. For canvas widgets, you need to update the scrollregion after adding new items. most simply like this:

#### text

Scrollable editable multiline text with many formatting options. Can also contain images and embedded widgets. The default wrapping setting is "none", so you might need a horizontal scrollbar to see all of long lines. In many cases it's more user-friendly to configure a text widget as -wrap word - then you only need a vertical scrollbar at most.
Positions in a text widget are specified as line.column, where line starts from 1, and column from 0, so 1.0 is the very first character in a text widget. Example how to delete all contents:
For highlighting part of the contents, you can define tags and assign them to subsequences:

#### toplevel

Standalone frame window, mostly with decorations (title bar, buttons) from the window manager. When you start Tk, you receive an initially empty toplevel named "." (one dot). If you want more toplevels, create them like this:
Such toplevels are logically children of ".". To assign a nice title to a toplevel, use
You can also control the geometry (size and position) of a toplevel with

### Geometry managers

The purpose of geometry managers is to compute the required height, width, and location of widgets, and map them on screen. Besides grid, pack and place, the canvas and text widgets can also manage embedded widgets.
Calls to geometry managers always start with the manager's name, then (mostly) one or more widget names, then any number of -name value options

#### grid

This geometry manager is best suited for tabular window layout consisting of rows and columns. Example, to put three widgets in a horizontal row:
The -sticky option indicates what side of its box the widget should stick to, in compass direction; "news" is north-east-west-south", i.e. all four sides.
Here's a minimal solution to display a table (list of lists) in a grid of labels:

#### pack

This used to be the workhorse manager, but in recent years has been less popular than grid. Anyway, it is still good for cases where you have widgets aligned in only one direction (horizontally or vertically). For more complex layouts, one used to insert intermediate frames, but grid makes such jobs just easier. Example:

#### place

This geometry manager is not often used, mostly for special applications, like when you want to highlight the current tab of a tab notebook. It allows pixel-precise placement of widgets, but is less dynamic in reaction to resizing of the toplevel or inner widgets.

### Dialogs

Dialogs are toplevels that are to tell a message, or answer a question. You don't have to assign a widget path name to them. Just call them as functions and evaluate the result (often "" if the dialog was canceled).

#### tk_getOpenFile

A file selector dialog (limited to existing files). Returns the selected file with path name, or "" if canceled.

#### tk_getSaveFile

A file selector dialog, which also allows specification of a not existing file. Returns the selected file with path name, or "" if canceled.

#### tk_messageBox

A simple dialog that displays a string and can be closed with an "OK" button. Example:

#### tk_chooseColor

Displays a dialog for color selection. The returned value is the selected color in one of the representations conformant to Tcl's comprehension of such information; on Microsoft Windows systems this might constitute a hexadecimal string in the format “#RRGGBB”. Upon abortion of the process, the empty string is instead delivered. The dialog may be configured to preselect a certain default color via the “-initialcolor” option, a subordination into a parent widget with “-parent”, and a title caption through “-title”.

#### Custom dialogs

Besides the prefabricated dialogs that come with Tk, it's also not too hard to build custom ones. As a very simple example, here's a "value dialog" that prompts the user for to type in a value:
Test:
For a more elaborate example, here is a record editor dialog (multiple fields, each with a label and entry (or text for multi-line input)):
Quick test:

### Megawidgets made easy

The term "megawidgets" is popular for compound widgets that in themselves contain other widgets, even though they will hardly number a million (what the prefix Mega- suggests), more often the child widgets' number will not exceed ten.
To create a megawidget, one needs one proc with the same signature as Tk widget creation commands. This proc will, when called, create another proc named after the widget, and dispatch methods either to specific handlers, or the generic widget command created by Tk.

#### A little notebook

Plain Tk does not contain a "notebook" widget, with labeled tabs on top that raise one of the "pages", but it's easy to make one. This example demonstrates how the tabs are implemented as buttons in a frame, and how the original Tk command named like the frame is "overloaded" to accept the additional add and raise methods:
Test and demo code:

### Binding events

Events within Tcl/Tk include actions performed by the user, such as pressing a key or clicking the mouse. To react to mouse and keyboard activity, the bind command is used. As shown in the calculator example:
The bind keyword operates on .e and associates the event related to the <return> event. The following bracket indicates a start of a set of procedures which are executed when the event is performed.

### BWidget

BWidget is an extension to Tk written in pure Tcl (therefore it can even run on Windows Mobile-driven cell phones). It offers mega-widgets (all class names starting with Uppercase) like
* ComboBox
* NoteBook
* Tree
Screenshot of a NoteBook and a Tree, on a PocketPC under Windows/CE

#### Tree examples

Here is a "hello world" example of a Tree widget (this is a complete script). The root node is constantly called root, for the others you have to make up names:
The famous typewriter test sentence represented as a syntax tree:

### Tk resources
#### Colors

Colors in Tk can be specified in three ways:
* a symbolic name, like: red green blue yellow magenta cyan
* a hex string preceded by a #: #RGB, #RRGGBB, #RRRRGGGGBBBB
* a list of three non-negative integers
The last form is only returned by commands. To specify a color to a command, you'll have to hex-format it. For instance, white could be described as #FFFFFF.
To turn a symbolic name into its RGB components:
Here is the list of defined color names (as from X11's rgb.txt):
In addition, the following are defined on Windows:

#### Cursors

For every widget, you can specify how the mouse cursor should look when over it. Here's the list of defined cursor names:
A little tool that presents the cursor names, and shows each cursor shape when mousing over:

#### Fonts

Fonts are provided by the windowing system. Which are available depends on the local installation. Find out which fonts are available with
The typical description of a font is a list of up to three elements:
Example:
Family is a name like Courier, Helvetica, Times, ... Best pick one of the names delivered by font families, though there may be some mappings like "Helvetica" -> "Arial"
Size is point size (a typographer's point is 1/72th of an inch) if positive, or pixel size if negative. Normal display fonts often have a size of 9 or 10.
Style can be a list of zero or more of bold, italic, underlined, ...

#### Images: photos and bitmaps

Tk allows simple yet powerful operations on images. These come in two varieties: bitmaps and photos. Bitmaps are rather limited in functionality, they can be specified in XBM format, and rendered in configurable colors.
Photos have much more possibilities - you can load and save them in different file formats (Tk itself supports PPM and GIF - for others, use the Img extension), copy them with many options, like scaling/subsampling or mirroring, and get or set the color of single pixels.
Setting can also do rectangular regions in one go, as the following example shall demonstrate that creates a photo image of a tricolore flag (three even-spaced vertical bands - like France, Italy, Belgium, Ireland and many more). The default is France. You can specify the width, the height will be 2/3 of that. The procedure returns the image name - just save it in -format GIF if you want:

### Debugging Tk programs

A Tk program under development can be very rapidly debugged by adding such bindings:
This works only on Windows and Macintosh (pre-OS-X) and brings up a console in which you can interact with the Tcl interpreter, inspect or modify global variables, configure widgets, etc.
This starts a new instance of the current program (assuming you edited a source file and saved it to disk), and then terminates the current instance.
For short debugging output, one can also use the window's title bar. For example, to display the current mouse coordinates when it moves:

### Other languages

Other programming languages have modules that interface and use Tcl/Tk:
* In R (programming language), there's a tcltk library, invoked with the command library(tcltk)
* In Python, there's a tkinter module, invoked with import tkinter or from tkinter import *
* Common Lisp can communicate with Tcl/Tk via several externally available libraries, including CL-TK and LTK