Wiki
Download
Manual
Eggs
API
Tests
Bugs
show
edit
history
You can edit this page using
wiki syntax
for markup.
Article contents:
[[tags: egg tkgui]] == tkgui [[toc:]] === 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|https://codeberg.org/jrapdx/tkgui]] === Requirements * [[srfi-1]] * [[srfi-13]] * [[srfi-14]] * [[nutils]] === mktkgui {{mktkgui}} is easy to use, with only 2 required options. mktkgui {options} -src string Space-separated list of Scheme source files [required] -app name Output app basename (without extension) [required] -imports string Space-separated list of additional extension imports -stop 1..4/symbol Stop @stage: 1/obj, 2/stk, 3/dll/so, 4/exe, #f/don't stop -install appname (Re)installs compiled <app>(.exe) and (lib)<app>(.dll/so) -uninstall appname Uninstalls previously installed <app basename> -gui Windows only: toggles 'console'/'gui', default="gui" -verbose Toggles verbose output, default="on" -static Toggles static egg libs (default="off") -config filename Config file to use, default="ext-config.scm" -defaults Prints built-in default settings. -settings Prints configured settings (e.g., ext-config.scm) -help Prints this text and exits Command line options {{-gui}}, {{-verbose}}, {{-static}} work as switches, that is, when used without a value produce the inverse effect of the corresponding configuration specifier. However these options also accept #t or #f values which override toggling configuration settings. ({{gui}} options are Windows only.) Since default {{gui}} and {{verbose}} options are #t, using the command line -<option> or -<option> '#t' forces the option ''off''. Conversely, -<option> '#f' means option is ''on''. This table summarizes the (default) interaction of config and command line options: ---- <table> <tr><th>Config default (on/off)</th><th>Cmd line</th><th>Cmd line (force off)</th><th>Cmd line (force on)</th></tr> <tr><td>(winflag . (mwindows)) (on)</td><td>-gui (off)</td><td>-gui '#t'</td><td>-gui '#f'</td></tr> <tr><td>(winflag . ()) (off)</td><td>-gui (on)</td><td>-gui '#f'</td><td>-gui '#t'</td></tr> <tr><td>(verbose . #t) (on)</td><td>-verbose (off)</td><td>-verbose '#t'</td><td>-verbose '#f'</td></tr> <tr><td>(static-egg-libs . #f) (off)</td><td>-static (on)</td><td>-static '#f'</td><td>-static '#t'</td></tr> </table> ---- Note: on the command line, #t and #f have to be enclosed in single or double quotes. (In shell syntax '#' initiates a line comment.) <enscript highlight='python'> ## static linking of egg libs (with default configuration) $ mktkgui -src myapp.scm -app myapp -static ## static linking of egg libs (default configuration) $ mktkgui -src myapp.scm -app myapp -static '#t' $ mktkgui -src myapp.scm -app myapp -static '#t' \ -config "my-config.scm" ## force shared egg lib linking $ mktkgui -src myapp.scm -app myapp -static "#f" ## this invocation turns off verbose terminal output $ 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. ## installed to configured locations. </enscript> === How mktkgui compiles applications {{mktkgui}} manages 4 major compiled stages without user intervention: # Creates <app-name>.c, Tcl extension code, and compiled (by $(CC)) to an obj file (*.o or *.obj). # Creates <app-name>-scheme-tk.c, containing source and 'glue' code. Then $(CSC) compiles this to a second obj file, using -link files if static egg libs linking is specified. # The above obj files (and egg *.o/obj files if linking statically) are used to form a shared library (a .dll or .so) that's a fully qualified Tcl/Tk extension with interacting Scheme and Tcl code, effectively producing a true "hybrid". # Lastly, a small dedicated runnable binary is generated that loads the dll/so, which 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 that ''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, the lambda's 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 values returned to it by Tcl. For example, these (tk ...) calls create a frame and interior button: <enscript highlight='scheme'> (define frm (tk 'frame ".frm")) ;; frm -> ".frm" (define frm.btn (tk 'button (string-append frm ".btn") -text "Press me" '-command '(lambda () (set! topvar #t) ...))) </enscript> [[Example|See complete example below.]] In addition to (tk ...) 3 convenience procedures are provided: * (tk/nm <widget> (names list) 'argument ...) * (tk/label (names list) "label text" 'argument ...) * (tk/button (names list) "button text" 'argument ...) The example can be written: <enscript highlight='scheme'> (define frm (tk 'frame '.frm)) (define frm.btn (tk/button `(,frm btn) "Press me" '-command '(lambda () ...))) </enscript> A complete example (example.scm): <enscript highlight='scheme'> (import scheme.base nutils ) (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 ".") </enscript> === 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. The option 'static-egg-libs' determines how extension libs are linked: static or shared. By default 'static-egg-libs' is #f, that is, shared linking is initial setting. Insert '(static-egg-libs . #t)' in local config file to enable linking statically. Note that on unix platforms static linking of egg libs requires the egg to be compiled with "-C" "-fPIC" added to csc-options in the egg's .egg file. Shared linking works with modified and unmodified eggs. Alternatively, as described above, the mktkgui command line '-static' option can be used to activate static egg library linking without changing the default. Example config: <enscript highlight='scheme'> ((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=")) </enscript> Note: list values should not have leading quotes ('). === Builtin options Options are overridden by options in local config file. ==== Unix defaults app-01 "-scheme-tk" cc "/usr/bin/gcc" cflag (-Og -g -fPIC) config-check "unix defaults" csc "/usr/local/bin/csc" csc-cflag (-C -g -C -fPIC) csc_stublibs (-L -ltclstub9.0 -L -ltkstub9.0) csclinkdir "." defs (-DUSE_TCL_STUBS -DUSE_TK_STUBS) dll ".so" dllflag ("-shared" "-o") exe "" exedir "/usr/local/bin" imports () includes (-I. -I/usr/local/include/chicken -I/usr/local/include) ldconfig "ldconfig" ldflags (-L/usr/local/lib -L.) libchkn (-lchicken) libdir "/usr/local/lib" libprefix "lib" link-list (srfi-1 srfi-13 srfi-14 nutils) obj ".o" platform "unix" rc "" static-egg-libs #f stublibs (-ltclstub9.0 -ltkstub9.0) sudo "sudo" tcltklibs (-ltcl9.0 -ltcl9tk9.0) verbose #t winflag () ==== Windows defaults app-01 "-scheme-tk" cc "c:/w64devkit/bin/gcc.exe" cflag (-Og -g) config-check "windows defaults" csc "c:/usr/local/bin/csc.exe" csc-cflag () csc_stublibs (-L -ltclstub -L -ltkstub) csclinkdir "." defs (-DUSE_TCL_STUBS -DUSE_TK_STUBS) dll ".dll" dllflag ("-mdll" "-o") exe ".exe" exedir "c:/usr/local/bin" exelib "c:/usr/local/bin" imports () includes (-I. -Ic:/usr/local/include/chicken -Ic:/usr/local/include) ldconfig "" ldflags (-Lc:/usr/local/lib -L.) libchkn (-lchicken) libprefix "" link-list (srfi-1 srfi-13 srfi-14 nutils) obj ".obj" platform "windows" rc "./rc" static-egg-libs #f stublibs (-ltclstub -ltkstub) sudo "" tcltklibs (-ltcl91 -ltcl9tk91) verbose #t winflag (-mwindows) === 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.7.3 Update documentation, additional command line option * v0.7.2 Option for static vs. shared linking of extensions * v0.7.0 Ported to FreeBSD * v0.6.4 Removed dependencies, simplify build. * v0.6.2 Revised documentation * v0.6.1/0.6.1.1 Minor corrections to info files * v0.6.0 Initial public release
Description of your changes:
I would like to authenticate
Authentication
Username:
Password:
Spam control
What do you get when you subtract 4 from 19?