t3x.org / pstk / pstk.html

PS/Tk Manual

Copyright (C) 2007 Nils M Holm < nmh @ t3x . org >

Using PS/Tk
Tk Procedures
Tile Procedures
Supported Widgets
PS/Tk Procedures

This manual presents a summary of the PS/Tk procedures resembling Tcl/Tk and Tile commands, plus a summary of PS/Tk's native procedures. It does not duplicate the information contained in the Tcl/Tk manual. To learn about the details of a Tk or Tile command or widget, please refer to the Tcl/Tk and Tile manuals.

Using PS/Tk

PS/Tk brings Scheme syntax to Tk and Tk graphics to Scheme. It lets you use nearly all Tcl/Tk functions from within a Scheme program.

What you need

In order to run PS/Tk, you need

Configuring PS/Tk

When you start PS/Tk without configuring it first, you will get an error message like this:

You need to choose a version of RUN-PROGRAM first.
Error: variable bottom is not bound.

To configure PS/Tk, load the file pstk.scm into a text editor and search for the string NON-PORTABLE (yes, in capitals). This is the beginning of the configurable section.

The least you must do here is to comment out the first version of run-program and uncomment the one that suits your system. You may have to uncomment a version of flush-output, too.

If you are using Chicken or Gambit, you also will have to decide whether you want to use keywords or not. See the code for details.

Your First PS/Tk Program

(load "pstk.scm")
(tk-start)
(let* ((label (tk 'create-widget 'label
                  'text: "Hello, World!"
                  'foreground: 'red))
       (quit-button (tk 'create-widget 'button
                        'text: "Goodbye"
                        'command: tk-end)))
  (tk/pack label quit-button)
  (tk-event-loop))

The first line loads PS/Tk. The second line launches an inferior Tcl/Tk process. The let* creates a label widget displaying Hello, World and a button saying Goodbye. The button shuts down PS/Tk whe pressed. Tk/pack packs the widgets, and tk-event-loop enters the event processing loop.

What Next?

Tcl/Tk commands translate quite directly to PS/Tk procedure calls:

Tcl/TkPS/Tk
frame .f (define f (tk 'create-widget 'frame))
button .f.b (define b (f 'create-widget 'button))

Note that literals like frame and button have to be quoted.

Options get a trailing colon (and have to be quoted, too):

Tcl/TkPS/Tk
b configure -text "Hi!" (b 'configure 'text: "Hi!")

Booleans, integers, lists, and strings are translated automatically between Scheme and Tcl, e.g.:

Tcl/TkPS/Tk
pack b -expand 0 (tk/pack b 'expand: #f)
b configure -width 50 (b 'configure 'width: 50)
bindtags . {. Tclsh all} (tk/bindtags tk '("." "Tclsh" "all"))

Strings and quoted symbols can both be used to form literals, but note that Scheme folds quoted symbols to lower case by default, so while this works fine:

Tcl/TkPS/Tk
pack b -fill 'both (tk/pack b 'fill: 'both)

this does not:

Tcl/TkPS/Tk
bind all <Button-1> {exit} (tk/bind 'all '<Button-1> tk-end)

because <button-1> (with a lower-case b) is not a valid event pattern. You must use a string in this case:

Tcl/TkPS/Tk
bind all <Button-1> {exit} (tk/bind 'all "<Button-1>" tk-end)

The Tk Widget

PS/Tk associates a widget named tk with the toplevel window that pops up when PS/Tk is started. All widgets created by this program are descendants of tk. For example, the procedure application

(tk 'create-widget 'label 'text: "foo!")

creates a label widget that is a child of tk.

Unless you are using the Snow version of PS/Tk, you can manipulate the tk widget like any other widget. For example, you can raise the toplevel window using

(tk/raise tk)

Unfortunately, this is not possible in the Snow version. When using the Snow port of PS/Tk, you have to resort to the Tcl/tk name of the window instead:

(tk/raise ".")

Tk Procedures

tk

Create widgets at the top level.

Application   (tk 'create-widget widget-type option [...]) => widget
Tcl equivalent   widget-type

Example:

(define b (tk 'create-widget 'button 'text: "Hello"))
; Tcl/Tk: button .b -text "Hello"

tk/after

Run procedures after a given number of milliseconds. When no procedure is given, sleep for the specified time.

Application   (tk/after ms [procedure ...]) => id
(tk/after cancel id) => ""
Tcl equivalent   after

Example:

(tk/after 1000 tk/bell)
; Tcl/Tk: after 1000 bell

tk/appname

Set or get the application name.

Application   (tk/appname [name]) => name
Tcl equivalent   tk appname

Example:

(tk/appname "new name")
; Tcl/Tk: tk appname "new name"

tk/bell

Ring the bell.

Application   (tk/bell [option ...]) => ""
Tcl equivalent   bell

Example:

(tk/bell)
; Tcl/Tk: bell

tk/bgerror

Invoke the Tcl/Tk error dialog. Deprecated.

Application   (tk/bgerror message) => unspecified
Tcl equivalent   bgerror

Example:

(tk/bgerror "an error occurred")
; Tcl/Tk: bgerror "an error occurred"

tk/bind

Bind events to actions.

Application   (tk/bind window) => patterns
(tk/bind window pattern) => ids
(tk/bind window pattern procedure) => ""
Tcl equivalent   bind

Notes: the form

`(+ ,(lambda () ...))

is used to add a procedure to a binding list rather than replacing existing procedures. The form

`(,(lambda (x) ...) %x)

is used to propagate event argument x to the procedure.

Example:

(tk/bind 'all "<Button-1>"
  `(,(lambda (x) (display x) (newline) #f) %x))
; Tcl/Tk: bind all <Button-1> {puts %x}

tk/bindtags

Set or get binding tags of a window.

Application   (tk/bindtags window) => tags
(tk/bindtags window tag-list) => ""
Tcl equivalent   bindtags

Example:

(tk/bindtags tk)
; Tcl/Tk: bindtags .

tk/caret

Set or get the caret location of a given window.

Application   (tk/caret window) => "-height h -x x -y y"
(tk/caret window ['height: h] ['x: x] ['y: y]) => ""
Tcl equivalent   tk caret

Example:

(tk/caret tk)
; Tcl/Tk: tk caret .

tk/choose-color

Invoke the Tk Color Chooser.

Application   (tk/choose-color [option ...]) => color
Tcl equivalent   tk_chooseColor

Example:

(tk/choose-color)
; Tcl/Tk: tk_chooseColor

tk/choose-directory

Invoke the Tk Directory Chooser.

Application   (tk/choose-directory [option ...]) => path
Tcl equivalent   tk_chooseDirectory

Example:

(tk/choose-directory)
; Tcl/Tk: tk_chooseDirectory

tk/clipboard

Access the clipboard.

Application   (tk/clipboard command [option ...]) => result
Tcl equivalent   clipboard

Example:

(tk/clipboard 'clear)
; Tcl/Tk: clipboard clear

tk/destroy

Destroy widgets.

Application   (tk/destroy widget [...]) => ""
Tcl equivalent   destroy

Example:

(tk/destroy tk)
; Tcl/Tk: destroy .

tk/dialog

Invoke a Tk dialog. Deprecated.

Application   (tk/dialog path title text bitmap default arg [...]) => button
Tcl equivalent   tk_dialog

Example:

(tk/dialog ".x"  "foo" "does this dialog suck?"
           'question 0 "yes" "no")
; Tcl/Tk: tk_dialog .x  "foo" "does this dialog suck?" \
;                   question 0 "yes" "no"

tk/event

Manage events.

Application   (tk/event command [option ...]) => result
Tcl equivalent   event

Example:

(tk/event 'generate tk "<Button-1>")
; Tcl/Tk: event generate . <Button-1>

tk/focus

Move or query the input focus.

Application   (tk/focus command [option ...]) => result
Tcl equivalent   focus

Example:

(tk/focus tk)
; Tcl/Tk: focus .

tk/focus-follows-mouse

Change the focus model from "click to focus" to "focus follows mouse".

Application   (tk/focus-follows-mouse) => ""
Tcl equivalent   tk_focusFollowsMouse

Example:

(tk/focus-follows-mouse)
; Tcl/Tk: tk_focusFollowsMouse

tk/focus-next

Return the next window in focus traversal.

Application   (tk/focus-next window) => window
Tcl equivalent   tk_focusNext

Example:

(tk/focus-next tk)
; Tcl/Tk: tk_focusNext .

tk/focus-prev

Return the previous window in focus traversal.

Application   (tk/focus-prev window) => window
Tcl equivalent   tk_focusPrev

Example:

(tk/focus-prev tk)
; Tcl/Tk: tk_focusPrev .

tk/get-open-file

Use the Tk Directory Chooser to present an "Open File" Dialog.

Application   (tk/get-open-file [option ...]) => path
Tcl equivalent   tk_getOpenFile

Example:

(tk/get-open-file)
; Tcl/Tk: tk_getOpenFile

tk/get-save-file

Use the Tk Directory Chooser to present a "Save File" Dialog.

Application   (tk/get-save-file [option ...]) => path
Tcl equivalent   tk_getSaveFile

Example:

(tk/get-save-file)
; Tcl/Tk: tk_getSaveFile

tk/grab

Set or query input grabs.

Warning: A global grab can lock your terminal.

Application   (tk/grab [command] [window]) => result
Tcl equivalent   grab

Example:

(tk/grab 'status tk)
; Tcl/Tk: grab status .

tk/grid

Manage grids (communicate with the grid geometry manager).

Application   (tk/grid command [option ...]) => result
Tcl equivalent   grid

Example:

(tk/grid 'info tk)
; Tcl/Tk: grid info .

tk/image

Manage images (bitmaps and pictures).

Application   (tk/image command [option ...]) => result
Tcl equivalent   image

Example:

(tk/image 'create 'photo 'name 'file: "name.gif")
; Tcl/Tk: image create photo name -file "name.gif"

tk/lower

Lower a toplevel window.

Application   (tk/lower window) => ""
Tcl equivalent   lower

Example:

(tk/lower tk)
; Tcl/Tk: lower .

tk/message-box

Invoke a Tk Message Box.

Application   (tk/message-box [option ...]) => button
Tcl equivalent   tk_messageBox

Example:

(tk/message-box 'message: "Hello!")
; Tcl/Tk: tk_messageBox -message "Hello!"

tk/option

Manage the Tk Option Database.

Application   (tk/option command [option ...]) => result
Tcl equivalent   option

tk/pack

Manage windows (communicate with the packer).

Application   (tk/pack command [option ...]) => result
Tcl equivalent   pack

Example:

(let ((b (tk 'create-widget 'button)))
  (tk/pack b 'side: 'left 'expand: #t 'fill: 'both))
; Tcl/Tk: button .b
;         pack .b -side left -expand 1 -fill both

tk/place

Place windows (communicate with the placer).

Application   (tk/place command [option ...]) => result
(tk/place window [option ...]) => result
Tcl equivalent   place

Example:

(tk/place (tk 'create-widget 'label 'text: "foo")
          'in: tk)
; Tcl/Tk: label .l -text "foo:
;         place .l -in .

tk/popup

Post menues.

Application   (tk/popup menu x y [entry]) => unspecified
Tcl equivalent   tk_popup

tk/raise

Raise a toplevel window.

Application   (tk/raise window) => ""
Tcl equivalent   raise

Example:

(tk/raise tk)
; Tcl/Tk: raise .

tk/scaling

Set or get the number of pixels per point on a given display.

Application   (tk/scaling ['displayof: window] factor) => ""
(tk/scaling ['displayof: window]) => factor
Tcl equivalent   tk scaling

Example:

(tk/scaling)
; Tcl/Tk: tk scaling

tk/selection

Manage the X11 display selection.

Application   (tk/selection command [option ...]) => result
Tcl equivalent   selection

Example:

(tk/selection 'get)
; Tcl/Tk: selection get

tk/update

Force processing of all pending events.

Note: This procedure may cause dead locks. Use with extreme care.

Application   (tk/update ['idletasks]) => ""
Tcl equivalent   update

Example:

(tk/update 'idletasks)
; Tcl/Tk: update idletasks

tk/useinputmethods

Query, activate or de-activate XIM filtering.

Application   (tk/useinputmethods ['displayof: window] [boolean]) => result
Tcl equivalent   tk useinputmethods

Example:

(tk/useinputmethods #f)
; Tcl/Tk: tk useinputmethods 0

tk/wait

Wait for a variable to change or a window to become visible or destroyed.

Note: better use tk-wait-for-window and tk-wait-until-visible to wait for window events.

Application   (tk/wait type window) => ""
(tk/wait variable name) => ""
Tcl equivalent   tkwait

Example:

(tk/wait 'window tk)
; Tcl/Tk: tkwait window .

tk/windowingsystem

Return a string naming the underlying windowing system.

Application   (tk windowingsystem) => "system"
Tcl equivalent   tk windowingsystem

Example:

(tk/windowingsystem)
; Tcl/Tk: tk windowingsystem

tk/winfo

Query information about windows managed by Tk.

Application   (tk/winfo command [option ...]) => result
Tcl equivalent   winfo

Example:

(tk/winfo 'exists tk)
; Tcl/Tk: winfo exists .

tk/wm

Communicate with the window manager of the underlying platform.

Application   (tk/wm command [option ...]) => result
Tcl equivalent   wm

Example:

(tk/wm 'geometry tk)
; Tcl/Tk: wm geometry .

Tile Procedures

These procedures work only if you have the Tile theming engine installed. They may also work if you are using Tcl/Tk 8.5 or a later version (which has Tile built into it). You can download Tile here:

http://tktable.sourceforge.net/tile/

ttk-map-widgets

Map the given widgets to Tile, so that the corresponding Tile widgets are used instead of Tk widgets automatically.

Application   (ttk-map-widgets 'all) => unspecific
(ttk-map-widgets 'none) => unspecific
(ttk-map-widgets widget-list) => unspecific
Tile equivalent   n/a

The all argument maps all Tk widgets that have counterparts in Tile (as well as the widgets that do not exist in Tk). The none argument unmaps all widgets. Specifying a list of widget types will map exactly those widgets. For instance:

(ttk/map-widgets '(button))

Maps all buttons to ttk::button, so

(tk 'create-widget 'button)

implicitly becomes

(tk 'create-widget 'ttk::button)

Note that using ttk/map-widgets shadows the native Tk widgets that are mapped to Tile. I.e. the native Tk button becomes inaccessible in the above example.

Example:

(ttk/map-widgets 'all)

ttk/available-themes

Return a list of available Tile themes.

Application   (ttk/available-themes) => list
Tcl equivalent   tile::availableThemes

Example:

(ttk/available-themes)
; Tcl/Tk: tile::availableThemes

ttk/set-theme

Activate a Tile theme. The theme must be a one of those returned by ttk/available-themes.

Application   (ttk/set-theme theme) => theme
Tcl equivalent   tile::setTheme

Example:

(ttk/set-theme "default")
; Tcl/Tk: tile::setTheme "default"

Supported Widgets

To create a toplevel widget, use

(tk 'create-widget widget-type)

To create a sub-widget use

(widget 'create-widget widget-type)

To create a Tile widget rather than a Tk widget, use

(widget 'create-widget ttk::widget-type)

or map the desired widgets using ttk-map-widgets.

Widget TypeTkTile
buttonyy
canvasy-
combobox-y
checkbuttonyy
entryyy
frameyy
labelyy
labelframeyy
listboxy-
menuy-
menubuttony-
messagey-
Widget TypeTkTile
notebook-y
panedwindowy-
progessbar-y
radiobuttony-
scaleyy
scrollbaryy
separator-y
spinboxy-
texty-
toplevely-
treeview-y
   

"y" means "yes, this widget is supported".

PS/Tk Procedures

tk-dispatch-event

Dispatch one Tk event. There is normally no need to use this procedure in user-level code. The only exception is a situation where a long computation takes place. In this case you can use tk-dispatch-event to service asynchronous events periodically.

Note: Tk-dispatch-events may cause race conditions. Use with care!

Application   (tk-dispatch-event) => ()

Example:

(tk-dispatch-event)

tk-end

Shut down PS/Tk by terminating the inferior Tcl/Tk process.

Application   (tk-end) => ()

Example:

(tk-end)

tk-eval

Submit a command to Tcl/Tk for evaluation, return its result.

Application   (tk-eval Tcl-command) => result

Example:

(tk-eval "bell")

tk-event-loop

Enter the main event loop. This procedure does not return until PS/Tk is shut down using tk-end.

Application   (tk-event-loop) => unspecified

Example:

(tk-event-loop)

tk-get-var

Retrieve the value of a Tk variable. The variable must be declared using tk-var first.

Application   (tk-get-var variable) => value

Example:

(tk-var 'x)
(tk-get-var 'x)

tk-id->widget

Retrieve the procedure associated with an (internal) widget id. Not really needed. May get removed in a future release.

Application   (tk-id->widget name) => procedure

tk-set-var!

Set the value of a Tk variable. The variable must be declared using tk-var first.

Application   (tk-set-var! variable value) => value

Example:

(tk-var 'x)
(tk-set-var 'x "some value")

tk-start

Start the inferior Tcl process (tclsh), initialize the internal state of PS/Tk, and load Tk and Tile (if present). This procedure opens the initial Tk window.

Application   (tk-start) => ()

Example:

(tk-start)

tk-var

Define a Tk variable to be used by PS/Tk. Such variables are created in a separate namespace and do not interfere with other Tcl/Tk variables.

Application   (tk-var name) => tk-name

Example:

(tk-var 'foo)

tk-wait-for-window

Wait for a given window to be destroyed. This is basically the same as tk/wait 'window, but more reliable. Asynchronous events are serviced while PS/Tk waits.

Application   (tk-wait-for-window window) => ()

Example:

; This expression will not terminate until the window w
; is destroyed (by pressing the button b).
(let* ((w (tk 'create-widget 'toplevel))
       (b (w 'create-widget 'button 'text: "Bye"
             'command: (lambda () (tk/destroy w)))))
  (tk/pack b)
  (tk-wait-for-window w))

tk-wait-until-visible

Wait for a given window to become visible. This is basically the same as tk/wait 'visibility, but more reliable. Asynchronous events are serviced while PS/Tk waits.

Application   (tk-wait-until-visible window) => unspecific

Example:

; This expression will not terminate until the window w
; actually becomes visible.
(let ((w (tk 'create-widget 'toplevel)))
  (tk-wait-until-visible w))

tk-with-lock

Run a procedure with nested callbacks disabled. While the procedure runs, no asynchronous events are serviced (except by tk-wait-for-window). Asynchronous events that occur while the procedure executes will never be serviced.

Tk-with-lock is typically used to protect procedures manipulating state that could be messed up by subsequent asynchronous events.

Application   (tk-with-lock procedure) => result

Example:

(tk 'create-widget 'button
    'command: (lambda ()
                (tk-with-lock
                  (lambda () do-something-critical))))