tkgui

  1. tkgui
    1. Description
    2. Author
    3. Repository
    4. Requirements
    5. mktkgui
    6. Running compiled programs
    7. Scheme GUI syntax
    8. Configuration
    9. Windows *.rc files
    10. License
    11. Version History

Description

tkgui is a Chicken extension for creating GUI applications on Windows and unix platforms. tkgui leverages the venerable Tcl/Tk toolkit through its C-api enabling good performance and uncomplicated deployment.

The egg compiles to an executable, mktkgui, the primary user interface, and 4 extensions. While the extensions export generally useful procedures and macros this documentation focuses on using mktkgui.

Author

Jules Altfas

Repository

https://codeberg.org/jrapdx/tkgui

Requirements

mktkgui

mktkgui is easy to use, with only 2 required options.

 mktkgui {options}
 -src string         Space-separated list of Scheme source files [required]
 -app string         Target app basename (without extension) [required]
 -imports string     Space-separated list of additional library imports
 -stop 1..4/symbol   Stop @stage: 1/obj, 2/stk, 3/dll/so, 4/exe, #f/don't stop
 -install appnm      (Re)installs compiled app(.exe)
 -uninstall appnm    Uninstalls previously installed appnm
 -gui                Windows only: sets console mode, default is gui mode.
 -config filename    Config file (per directory). [default: "ext-config.scm"]
 -defaults           Prints built-in default settings.
 -settings           Prints configured settings (e.g., ext-config.scm)
 -verbose            Toggles verbose output (default is #t).
 -help               Prints this text and exits

Invocation is straightforward:

 $ mktkgui -src my-gui-app.scm -app myapp -verbose
 config-check: ext-config.scm
 myapp.obj -> OK.
 myapp-scheme-tk.obj -> OK.
 myapp.dll -> OK.
 myapp.exe -> OK.
 install: myapp.dll and myapp.exe -> OK.

myapp.dll/so and myapp(.exe) are installed to (configured) locations.

mktkgui manages 4 major compiled stages without user intervention:

  1. Creates myapp.c, Tcl extension code, and gcc-compiled to obj file.
  2. Creates myapp-scheme-tk.c, source+'glue' code and linked library objs, csc-compiled to an obj file.
  3. The above obj files are linked to form a shared library that's a fully qualified Tcl/Tk extension, a "Siamese twin" containing the Scheme program and Tcl code.
  4. Lastly, a dedicated small runnable binary that loads the dll/so, and starts the GUI program.

Running compiled programs

On Windows, applications can be launched directly from the installation directory. Assuming the app was compiled in gui mode, a console won't be rendered. Alternatively using a link or "shortcut" allows controlling program invocation. Note that attempting to launch from the source directory may produce errors about finding Tcl/Tk init files. Placing a copy of (or symbolic link to) the Tk .dll in the source directory resolves the issue.

Unix systems generally don't require anything special. Command-line invocation or shell scripts can be employed.

Scheme GUI syntax

All Scheme to Tcl/Tk translations are handled by the tk procdure:

 (tk 'widget-or-Tcl-command 'argument|"argument" ... '(lambda () ...))

Arguments are symbols or strings, except callbacks are lists and must be the last argument on the command line. A callback has the form of a Scheme (lambda) that takes no arguments. It is always an explicit list. The body of the lambda can contain any expressions including (tk ...) commands.

However it's important to note that callbacks do not have lexical scope, that is, its expressions can only access toplevel Scheme variables and procedures. (Tcl/Tk itself follows the same rule.) OTOH (tk ...) can call any Tk command and many Tcl commands. (tk ...) returns any values returned to it by Tcl.

For example, these (tk ...) calls create a frame and interior button:

 (define frm (tk 'frame ".frm")) ;; frm -> ".frm"
 (define frm.btn (tk 'button (string-append frm ".btn") -text "Press me"
                     '-command '(lambda () (set! topvar #t) ...)))

See complete example below.

In addition to (tk ...) 3 convenience procedures are provided:

The above example can be written:

 (define frm (tk 'frame '.frm))
 (define frm.btn (tk/button `(,frm btn) "Press me" '-command '(lambda ()
                                                                ...)))

A complete example (example.scm):

 (import scheme.base scmtkutils )
 (tk 'wm 'withdraw ".")
 (define rr 122)
 (tk 'font 'configure 'TkDefaultFont '-family "helvetica" '-size "10")
 (tk 'font 'configure 'TkCaptionFont '-family "helvetica" '-size "10")
 (define frm0 (tk 'ttk::labelframe ".frm0" '-text "Msgs:"))
 (define msgs (tk/nm 'text `(,frm0 outmsg)
                  '-font "-family helvetica -size 10"
                  '-wrap 'word
                  '-width 32 '-height 9))
 (printnl 'expr (tk "expr {122 * 3}" "") )
 (define (update-msg newmsg)
   (tk msgs 'replace "@0,0" 'end newmsg))
 (update-msg "Start...")
 (define btn1
   (tk/button `(,frm0 btn) "Press here" 
     '-command
     '(lambda ()
        (tk frm0 'configure '-text "Output:")
        (tk 'tk_messageBox '-message
                             (combine "button works!\nrr is " rr))
        (update-msg (combine "Great job! Now at " rr))
        (set! rr (+ rr 1)) 'ok)))
 (tk 'grid frm0 '-row 0 '-column 0 '-padx 20 '-pady 20) 
 (tk 'grid msgs '-row 0 '-column 0 '-padx 10 '-pady 12)
 (tk 'grid btn1 '-row 1 '-column 0 '-padx 22 '-pady "9 19")
 (tk 'wm 'deiconify ".")

Configuration

mktkgui has platform-specific built-in configuration which is overridden by values contained in config files. The config file settings are per directory, each source directory can have its own config file. In fact there can be several configs in a directory. The default directory config file is "ext-config.scm". Config files with different names can be selected using the '-config' command line option.

Config files are expected to contain a Scheme alist. When keys (symbols) match built-in keys the associated default values are replaced by the config value (string, list, #f/#t). Default/configured settings are printed to the terminal when a '-defaults or '-settings' argument is given to mktkgui.

Example config:

 ((cc . "/usr/local/bin/gcc")
  (csc . "/usr/local/bin/csc")
  (includes . (-I. -I/usr/local/include/chicken -I/usr/local/include))
  (csclinkdir . "/usr/local/lib/chicken/12")
  (imports . (myegg my-other-egg))
  ...
  (config-check . "=gui-prog/gui-config.scm="))

Note: list values should not have leading quotes (').

Windows *.rc files

Windows uses *rc files to include resources like icons, cursors and metadata in a library or executable. In a Tk application, .rc data isn't really optional as it contains rules defining geometry of widget layout.

Fortunately it's not difficult to manage. The Tk source distribution includes an 'rc' directory under 'win' in the source tree. Run the './configure' script in the win directory to generate 'wish.exe.manifest'. If not already copied, copy wish.exe.manifest to the rc directory and copy the rc dir to your GUI program location.

Creating a unique icon for an app is a good idea. Use the Tk icon as a template, replace the default Tk icon with the new one also named 'tk.ico'. To complete this customization, place you app 'tk.ico' in the Tk rc directory. Finally, rename the tcl9tk9x.dll and libtcl9tk9x.dll.a files. This requires editing the Makefile, as described in detail in the doc/mktkgui.html in the tkgui git repo. http://codeberg.org/jrapdx/tkgui/src/branch/main/doc

License

Copyright (c) 2025 Jules Altfas

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Version History

v0.6.2 Revised documentation

v0.6.1/0.6.1.1 Minor corrections to info files

v0.6.0 Initial public release