1. An Introduction to Gui
Gui simplifies the creation of resilient Tk user interfaces using a
model similar to that of HTML Markup/CSS/Javascript:
| HTML | GUI |
| Markup | Layout a nested Tcl list with tags based on Tk class names |
| CSS | Styles a definition language based on pattern matching rules. |
| Javascript | Tcl contained in the script tag. |
1.1 Layout
A GUI layout specifies a hierarchical set of tags containing attributes and
content-values.
Tags are usually just the Tk class name.
After the tag can be a +/-:
the + flag is used to indicate a child sub-tree.
Lastly are the
attributes to modify the layout, such as pack positioning and scroll-bars.
Here is a simple GUI layout:
{Toplevel + -title "Simple Editor"} {
{Text - -pos * -scroll *} {}
{Frame + -pos _ -subpos l} {
Button Save
Button Load
Button Quit
{Entry - -id status -pos *l} {}
}
}
1.2 Styles
Styles are used in a layout to abstract the use of Tk
options such as colors, fonts and images.
This avoids hard-coding options which is convenient in small applications,
but in larger applications
tends to lead to excess complexity.
Styles also apply options fault tolerantly such that errors become
warnings that are seen only at development time (ie. with -Wall).
{Toplevel + -title "Simple Editor"} {
{style} {
Button { -bg DarkKhaki }
.save { -bg DarkGreen }
.txtwin { -bg Khaki }
Entry.status { -bg LightGray -state disabled }
Toplevel {
@defimages { bled greenball }
}
.bsave { -image ^bled -compound left }
}
{Text - -id txtwin -pos * -scroll *} {}
{Frame + -pos _ -subpos l} {
{Button - -id save -id bsave} Save
Button Load
Button Quit
{Entry - -id status -pos *l} {}
}
}
In a style definition, the dot-prefix patterns will match -id attribute names, while
title-case patterns will match tags/widget-class names.
Note that we can define images once in the Toplevel using @deficons and
then apply them with image lookups using ^.
1.3 Script
Unless prototyping is the end goal,
an application usually requires at least some code.
This is added with a script tag. Using an -id
attribute will setup variables to dereference widgets from within code
- (w,NAME) - The widget.
- (v,NAME) - The -variable or -textvariable.
eg.
{script} {
array set _ { file "" }
proc Quit {_} { ::Delete $_ }
proc Load {_} {
upvar $_ {}
set fn [tk_getOpenFile]
if {$fn == ""} return
Text delete $(w,txtwin) 1.0 end
Text insert $(w,txtwin) end [*fread $fn]
set (file) $fn
set (v,status) "[mc {Loaded file}]: $(file)"
}
proc Save {_} {
upvar $_ {}
if {$(file) == ""} { set (file) [tk_getOpenFile] }
if {$(file) == ""} return
*fwrite $(file) [Text get $(w,txtwin) 1.0 end]
set (v,status) "[mc {Saved file}]: $(file)"
}
}
{Toplevel + -title "Simple Editor"} {
{Text - -id txtwin -pos * -scroll *} {}
{Frame + -pos _ -subpos l} {
Button Save
Button Load
Button Quit
{Entry - -id status -pos *l} {}
}
}
Note that in the above Tk code is written using the widget class command
(.ie Text).
This is the mechanisim which allows code to be validated.
Note also the use of Tod $_, in providing simple object-like
functionality.
1.4 Dialogs and Menus
An application can define dialogs using Toplevel and Menu.
{Toplevel + -id tlinput -ns Input} {
{Entry - -pos _} {}
Button Ok
}
{Menu + -label Main} {
{menu + -label File} { x Open x Save }
{menu + -label Edit} { x Copy x Paste }
}
{Menu + -id mpop -label IO} {
x Read
x Write
}
{Toplevel +} {
style {
.txt {
@bind { <Control-g> !tlinput <3> !mpop }
}
}
{Text - -pos * -id txt } {}
}
The following rules apply:
- The first defined Toplevel with no id or the id main will be the main window.
- The first defined Menu with no id or an id ending in mainmenu is used as a toplevel menu.
The main Toplevel can use a @bind style to trigger opening Dialogs or Menus.
(or use Tk::gui::toplevel from the program).
© 2008 Peter MacDonald