[Tkinter-discuss] Hooking into custom Tcl/Tk Widgets fromTkinter (vis)

Fredrik Lundh fredrik at pythonware.com
Fri May 13 19:29:05 CEST 2005

David King wrote:

> I still would like to hear from someone on how I'd invoke creation of my new
> custom widget and send it commands from python.  The C++ code registers
> callbacks for both these sorts of things with the Tcl interpreter, so that
> they become available as _Tcl/Tk_ commands.  But how can such commands be
> sent from python to Tkinter's Tcl/Tk interpreter?

if you have PIL on your machine, you can look at the tkImaging
and _imagingtk C modules, and the PIL/ImageTk.py module.

the latter contains the following block:

        tk = self.__photo.tk

            tk.call("PyImagingPhoto", self.__photo, block.id)
        except Tkinter.TclError, v:
            # activate Tkinter hook
                import _imagingtk
                    _imagingtk.tkinit(tk.interpaddr(), 1)
                except AttributeError:
                    _imagingtk.tkinit(id(tk), 0)
                tk.call("PyImagingPhoto", self.__photo, block.id)
            except (ImportError, AttributeError, Tkinter.TclError):
                raise # configuration problem; cannot attach to Tkinter

in this case, self.__photo happens to be a Tkinter PhotoImage object,
which has a "tk" attribute that contains the Tkinter context.  you'll find
the same attribute on all Tkinter widgets.

the tk.call() line calls PIL's custom Tcl command (PyImagingPhoto)
with a reference to the photo object as the first argument, and a
"block" attribute as the second argument.  the error handler, finally,
traps errors from Tcl, and attempts to (re)register the command for
the current Tcl interpreter.  (the interpaddr() function returns a
Tcl_Interp pointer cast to a long integer; the second case is there
to deal with old Tkinter versions.  to see how that case works, see
the _imagingtk.c source code).

to handle your acse, replace self.__photo with some suitable widget,
call your own command with suitable arguments, and replace _imagingtk
with your own C extension.  (if you need more sample code, grab the
PIL sources).


More information about the Tkinter-discuss mailing list