"RuntimeError: Calling Tcl from different appartment"

Eric Brunel eric_brunel at despammed.com
Tue Jun 22 12:12:06 CEST 2004

Peter Saffrey wrote:
> aahz at pythoncraft.com (Aahz) wrote in message news:<cb6u3m$9fn$1 at panix1.panix.com>...
>>In article <ced73313.0406210646.72fddfe4 at posting.google.com>,
>>Peter Saffrey <theoryboy at my-deja.com> wrote:
>>No clue why it used to work.  Why do you need to call Tk from multiple
> I'm writing an MP3 jukebox (don't laugh, it's just for fun). One
> thread controls the interface that shows the next few songs to be
> played and allows you to add to the list. The other thread plays the
> songs, removing them from the list in the process. To control this
> with one thread, I'd have to have the interface thread constantly
> listening for when the last song has finished so that it can remove it
> from the list and play the next one.

No you don't. There's one thing you can do in secondary threads wrt to Tkinter: 
posting events in Tkinter event queue via the event_generate method. Here is an 

import threading, time
from Tkinter import *

root = Tk()

def ping():
   while 1:
     root.event_generate('<<Ping>>', when='tail')

v = BooleanVar()
Checkbutton(root, variable=v, text='Ping!').pack(side=TOP)
Button(root, text='Quit', command=root.quit).pack(side=TOP)

def gotPing(event):
   v.set(not v.get())

root.bind('<<Ping>>', gotPing)

th = threading.Thread(target=ping)


The secondary thread make the check-button blink by generating custom <<Ping>> 
events in Tkinter event queue. Note the option when='tail' in event_generate is 
mandatory: if you don't set it, there's a chance that the event is treated 
immediatly without switching threads.

The code above works on Linux and Windows (there are other issues on Solaris, 
but I assume it won't be your target platform...)

- Eric Brunel <eric (underscore) brunel (at) despammed (dot) com> -
PragmaDev : Real Time Software Development Tools - http://www.pragmadev.com

More information about the Python-list mailing list