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

David King dking at nrao.edu
Fri May 13 17:15:44 CEST 2005


Thank you, Jeff, for your suggested code to send Tkinter's interpreter 
pointer into C++; along with Mr. Lundh's advice, you are helping me to piece 
together what I need to make my custom C++/Tk widget available in Tkinter.

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?

------


At the risk of putting too many questions in one email, I'll also mention 
the other main problem I'm wrestling with.  I need to understand the 
'interactive' aspects of Tkinter--i.e., how _both_ the Tkinter gui(s) and 
python's sommand-line interpreter can remain 'live' at the same time, each 
responding to its own type of input.  I need my user to ba able to send 
commands to my widget via python commands as well as via gui input.  I know 
that matplotlib (esp. on top of Tkinter, and operated from the IPython 
shell) manages to do this, and the matplotlib folks seem to think Tkinter 
even has advantages over other widgetsets such as GTK for interactive use. 
In the most elementary Tkinter examples I run, however, I must give up all 
further python input when I enter tk.mainloop().

IPython/matplotlib give hints that perhaps they manage the trick by creating 
a second thread for the Tkinter loop to run in.  That may be an ok solution, 
if I can truly understand where/how the one-thread-at-a-time-only locks need 
to be used (apparently both the python and Tcl interpreters each need such 
exclusivity; my widget library code will certainly need it as well).

Alternatively,... is there perhaps another way of merging the console and 
gui-event input streams, _without_ using more than one process/thread?

All suggestions welcome.  (Is there a 'bible' that lays all this out?  I'm 
willing to spring for the book if necessary).

David King




Jeff Epler wrote:
> On Fri, Apr 29, 2005 at 11:01:15AM -0600, David King wrote:
> 
>>But let's leave WCK aside and just talk about plain Tkinter for the moment. 
>> I'd like to understand how my custom C++/Tk widget could make itself known 
>>in the usual Tkinter world.  On the C++ side, essentially all my Tcl/Tk API 
>>calls interact with a tcl interpreter handle ('Tcl_Interp*').  Presumably I 
>>need to get the one Tkinter uses, instead of creating an interpreter myself 
>>(and also to let Tkinter handle the event loop, rather than doing _that_ 
>>myself).  I'm wondering how I get this handle from Tkinter.
> 
> 
> Here is some "C" code that I have used for this purpose.
> 
> // this code is in the public domain
> static Tcl_Interp *get_interpreter(PyObject *tkapp) {
>     long interpaddr;
>     PyObject *interpaddrobj = PyObject_CallMethod(tkapp, "interpaddr", NULL);
>     if(interpaddrobj == NULL) { return NULL; }
>     interpaddr = PyInt_AsLong(interpaddrobj);
>     Py_DECREF(interpaddrobj);
>     if(interpaddr == -1) { return NULL; }
>     return (Tcl_Interp*)interpaddr;
> }
> 
> 'PyObject *tkapp' is the thing returned by _tkinter.create(), and available as
> the 'tk' attribute on all Tkinter widgets.
> 
> This is not foolproof, because passing in an object like
>     class K:
>         interpaddr = 0 
> will soon lead to a crash.  But if you can trust the calling code to only pass in
> "real" interpreters, it should work just fine.
> 
> Jeff


More information about the Tkinter-discuss mailing list