Next: References Up: Using Tix with Previous: Using Tix with

## Freezing Tix Programs

Freeze (`$PYTHONHOME/tools/freeze/freeze.py`) make it possible to ship arbitrary Python programs to people who don't have Python. The shipped file (called a ``frozen" version of your Python program) is an executable, so this only works if your platform is compatible with that on the receiving end. The shipped file contains a Python interpreter and large portions of the Python run-time. Some measures have been taken to avoid linking unneeded modules, but the resulting binary is usually not small.

The Python source code of your program (and of the library modules written in Python that it uses) is not included in the binary - instead, the compiled byte-code is incorporated. This gives some protection of your Python source code, though not much - a disassembler for Python byte-code is available in the standard Python library. At least someone running ``strings" on your binary won't see the source.

With Python 2.x, is is possible to freeze Tix programs under Unix and Windows. Currently you must also deliver your frozen program with a set of Tcl/Tk/Tix library files. The best way to ship a frozen Tkinter program is to decide in advance where you are going to place the Tcl/Tk/Tix library files in the distributed setup, and then declare these directories in your frozen Python program using the TCL_LIBRARY, TK_LIBRARYand TIX_LIBRARYenvironment variables.

For example, assume you will ship your frozen program in the directory
`<root>/bin/windows-x86` and will place your Tcl/Tk/Tix library files in `<root>/lib/tcl8.3` in `<root>/lib/tk8.3` and `<root>/lib/tix8.1` respectively. Then placing the following lines in your frozen Python script before importing Tkinter or Tix would set the environment correctly for Tcl/Tk/Tix:

    import sys, os, os.path
    Parent = os.path.dirname(os.getcwd())
    RootDir = os.path.dirname(Parent)

    if os.name == "nt":
      sys.path = ['', '..\\ ..\\ lib\\ python-2.2']
      lib = RootDir + '\\ lib\\ '
      os.environ['TCL_LIBRARY'] = lib + 'tcl8.3'
      os.environ['TK_LIBRARY'] = lib + 'tk8.3'
      os.environ['TIX_LIBRARY'] = lib + 'tix8.1'
    elif os.name == "posix":
      sys.path = ['', '../../lib/python-2.2']
      lib = RootDir + '/lib/'
      os.environ['TCL_LIBRARY'] = lib + 'tcl8.3'
      os.environ['TK_LIBRARY'] = lib + 'tk8.3'
      os.environ['TIX_LIBRARY'] = lib + 'tix8.1'

This also adds `<root>/lib/python-2.2` to your Python path for any Python files such as `_tkinter.pyd` you may need.

Note that the dynamic libraries (such as tcl83.dll tk83.dll python22.dll under Windows, or libtcl8.3.so and libtcl8.3.so under Unix) are required at program load time, and are searched by the operating system loader before Python can be started. Under Windows, the environment variable `PATH` is consulted, and under Unix, it may be the the environment variable `LD_LIBRARY_PATH` and/or the system shared library cache (ld.so). An additional preferred directory for finding the dynamic libraries is built into the .dll or .so files at compile time - see the `LIB_RUNTIME_DIR` variable in the Tcl makefile. The OS must find the dynamic libraries or your frozen program won't start. Usually we make sure that the .so or .dll files are in the same directory as the executable, but this may not be foolproof.

A workaround to installing your Tcl library files with your frozen executable would be possible, by freezing the Tcl/Tk/Tix code into the dynamic libraries using the Tix Stand-Alone-Module (SAM) module. This is currently untested, but the maintainers of Tix would welcome feedback on this point.

There are some caveats using frozen Tkinter applications:

- Under Windows if you use the -s windows option (recommended), writing to stdout or stderr is an error. This makes debugging very dificult. If possible, develop and freeze first under Unix, where you can debug to stdout. Then make sure the frozen application never writes to stdout or stderr and try freezing under Windows.
- The Tcl `[info nameofexecutable]` will be set to where the program was frozen, not where it is run from.
- The global variables argc and argv do not exist.