GUI Scripting with Tcl/Tk
The thing that sets Tcl apart from more modern GUI scripting solutions is the way the Tk toolkit interacts with the Tcl code that does the work. Packages such as GTK or Qt are low-level libraries, written in C or C++. The script-level bindings to them work well enough, but there's always a big step down from the scripting language into the API of the GUI toolkit. Developers really need to understand the widgets with which they're working and must know how to configure and interrogate them using low-level calls directly to the widgets themselves.
The relationship between Tcl and Tk is much more of a peer-to-peer nature. The GUI toolkit operates at the same level as the language driving it, which makes the combination easy to work with. Take, for example, the listbox widget that contains the list of images to put in the Web page. In Visual Tcl, an attribute of the listbox widget, called the listvar, is presented, and I set it to a variable called ::imageList. ::imageList is a list variable in my Tcl code, and Tcl/Tk ensures that its contents always are reflected in the listbox widget. If I add, move or delete an item in that list variable, the contents of the listbox widget are updated immediately and automatically to display its contents. The code that handles the image list doesn't access or interact with the GUI at all. It simply keeps a single list variable in the correct state, safe in the knowledge that Tcl/Tk does the rest. Figure 5 shows this relationship.
More direct access to the widgets sometimes is required. Under these circumstances, Visual Tcl makes use of aliasing. In Tcl/Tk, the name of a widget depends on where it is in the widget tree. That name changes as container widgets, such as frames, are added and removed. To prevent the script writer from having to keep track of the full names of the important widgets, Visual Tcl allows the user to specify an alias—a short, easily memorable name by which the widget always is known. These short names can be looked up in a global associative array (also known as a hash or dictionary), so access to the widgets, wherever they might end up, always is easy. For example, I gave the Introduction text widget the alias IntroText. To fetch the text currently in that widget, the code in Listing 2 can be used.
Listing 2. Fetching the Contents of an Aliased Widget
... set introWidget $::widget(IntroText) set text [$introWidget get 1.0 end] ...
The ::widget array is provided automatically by the Visual Tcl generated code, so fetching the real name of the text widget is simple. Asking the widget to provide its current text, from line 1 character 0 to the end, also is easy.
The image display in the viewer window actually is a label widget in the center of the dialog. Tk can load an image from disk and create a pixmap from it with one line of code. When the user selects a new image file, a pixmap is created from it and a single command is used to set the label widget to show that image (Listing 3). In the actual script, I store the loaded pixmaps in a cache. This makes switching from one image to another and back again much sharper.
Listing 3. The image is loaded from the disk, and then the label widget is configured to show that image (Tk labels show images as well as text). The image appears on screen immediately.
... set loadedImage [image create photo -file $filename] $::widget(ImageLabel) configure -image $loadedImage ...
When the user clicks the Publish button, a Tcl function is called that creates the Web page. The workings of this code aren't especially relevant here. Suffice it to say that Tcl allows generation of an XML DOM using the TclXML extension and then allows the callout to the libxml2 XSLT processor, which generates the HTML. Getting a specialist package to do the hard work is, of course, the ace up the script writer's sleeve.
Although the Tcl/Tk script works nicely, it's hard to ignore the obvious gulf in quality between the appearance of a Tcl/Tk script and a more modern Qt or GTK one. Qt and GTK-based programs look much sharper than those using the Motif style of Tk widgets, plus they are themeable, whereas Tk isn't. Also compare built-in features, such as the file selector dialog—Tk's is no better than GTK's, and both are embarrassed by Qt's. Work continues in the Tcl community regarding these sorts of issues, but as with many mature technologies, improvements are slow in coming for fear of breaking existing code.
- Nmap—Not Just for Evil!
- Resurrecting the Armadillo
- High-Availability Storage with HA-LVM
- March 2015 Issue of Linux Journal: System Administration
- Real-Time Rogue Wireless Access Point Detection with the Raspberry Pi
- DNSMasq, the Pint-Sized Super Dæmon!
- Localhost DNS Cache
- Days Between Dates: the Counting
- The Usability of GNOME
- Linux for Astronomers