f



"RuntimeError: Calling Tcl from different appartment"

I am writing a multi-threaded Tkinter application. It worked fine with
Python 2.2 under Redhat 8.0, but I have recently moved across to
Debian (testing/unstable) and Python 2.3. Now I get the above error
message.

I read on this group somewhere that this is caused by calling Tk
functions from a different thread to where the interface is running.
Unfortunately, I really need to do this and cannot have all my Tk
calls within one thread. Is there a way around this? Why did it work
in 2.2 but not 2.3?

Thanks,

Peter
0
theoryboy (42)
6/21/2004 2:46:18 PM
comp.lang.python 77058 articles. 6 followers. Post Follow

3 Replies
2908 Views

Similar Articles

[PageSpeed] 20

In article <ced73313.0406210646.72fddfe4@posting.google.com>,
Peter Saffrey <theoryboy@my-deja.com> wrote:
>
>I am writing a multi-threaded Tkinter application. It worked fine with
>Python 2.2 under Redhat 8.0, but I have recently moved across to
>Debian (testing/unstable) and Python 2.3. Now I get the above error
>message.
>
>I read on this group somewhere that this is caused by calling Tk
>functions from a different thread to where the interface is running.

Yup.

>Unfortunately, I really need to do this and cannot have all my Tk
>calls within one thread. Is there a way around this? Why did it work
>in 2.2 but not 2.3?

No clue why it used to work.  Why do you need to call Tk from multiple
threads?
-- 
Aahz (aahz@pythoncraft.com)           <*>         http://www.pythoncraft.com/

"Typing is cheap.  Thinking is expensive."  --Roy Smith, c.l.py
0
aahz (2032)
6/21/2004 3:16:06 PM
aahz@pythoncraft.com (Aahz) wrote in message news:<cb6u3m$9fn$1@panix1.panix.com>...
> In article <ced73313.0406210646.72fddfe4@posting.google.com>,
> Peter Saffrey <theoryboy@my-deja.com> wrote:
> 
> No clue why it used to work.  Why do you need to call Tk from multiple
> threads?

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.

Peter
0
theoryboy (42)
6/22/2004 9:56:16 AM
Peter Saffrey wrote:
> aahz@pythoncraft.com (Aahz) wrote in message news:<cb6u3m$9fn$1@panix1.panix.com>...
> 
>>In article <ced73313.0406210646.72fddfe4@posting.google.com>,
>>Peter Saffrey <theoryboy@my-deja.com> wrote:
>>
>>No clue why it used to work.  Why do you need to call Tk from multiple
>>threads?
> 
> 
> 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 
example:

--tkinterNThreads.py-----------------------------------------
import threading, time
from Tkinter import *

root = Tk()

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

v = BooleanVar()
v.set(0)
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)
th.setDaemon(1)
th.start()

root.mainloop()
-------------------------------------------------------------

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...)

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

0
eric_brunel (214)
6/22/2004 10:12:06 AM
Reply: