There have been a number of posts about calling gui methods from other threads. Eric Brunel. has reccommended calling the gui's .event_generate method with data passed thru a queue. This worked great for me until trying to write to the gui from multiple threads. There I had problems: random typesof crashes almost all resulting in seg faults. I thought this info might help anyone trying to do the sameor at least save some time debugging.
I wrote a (hopefully) simple and minimal piece of code to demonstrate the problem included below. My knowledge of the Tcl/Tk interface is minimal. Another interesting thing is it fails on some systems and not on others. All Linux: Runs fine on: Dual Opteron Fedora5 Linux xxxx 2.6.16-1.2096_FC5 #1 SMP Wed Apr 19 05:14:26 EDT 2006 x86_64 x86_64 x86_64 GNU/Linux Singe Pentium Fedora4 uname info unavailable right now Fails on: Singe Xeon SuSE 10.1 Linux xxxx 2.6.16.13-4-smp #1 SMP Wed May 3 04:53:23 UTC 2006 i686 i686 i386 GNU/Linux Single Celeron 400 (Embedded BlueCat) Linux 2.6.7 #45 i686 i686 i386 (not copy pasted) Single Celeron 400 SuSE 10.1 - not available My solution (others have done the same) was to go back to having the gui thread call its own event_generate method with the event string passed in through queue and using a polling loop with after methods. Would someone please verify that this shouldn't be done for some reason such as thread-safety or point out what I'm doing wrong? It seems from some of the errors that the event data is getting overwritten. I've included the code, if anyone wants to see some of the errors I have saved them. --------------------------- from Tkinter import * import threading import Queue from time import sleep import random class Thread_0(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): count=0 while True: count+=1 hmi.thread_0_update(count) sleep(random.random()/100) class Thread_1(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): count=0 while True: count+=1 hmi.thread_1_update(count) sleep(random.random()/100) class HMI: def __init__(self): self.master=Tk() self.master.geometry('200x200+1+1') f=Frame(self.master) f.pack() self.l0=Label(f) self.l0.pack() self.l1=Label(f) self.l1.pack() self.q0=Queue.Queue() self.q1=Queue.Queue() self.master.bind("<<Thread_0_Label_Update>>",self.thread_0_update_e) self.master.bind("<<Thread_1_Label_Update>>",self.thread_1_update_e) def start(self): self.master.mainloop() self.master.destroy() ################################# def thread_0_update(self,val): self.q0.put(val) self.master.event_generate('<<Thread_0_Label_Update>>',when='tail') def thread_1_update(self,val): self.q1.put(val) self.master.event_generate('<<Thread_1_Label_Update>>',when='tail') def thread_0_update_e(self,e): while self.q0.qsize(): try: val=self.q0.get() self.l0.config(text=str(val)) except Queue.Empty: pass def thread_1_update_e(self,e): while self.q1.qsize(): try: val=self.q1.get() self.l1.config(text=str(val)) except Queue.Empty: pass ########################## if __name__=='__main__': hmi=HMI() t0=Thread_0() t1=Thread_1() t0.start() t1.start() hmi.start() --------------------------- -- http://mail.python.org/mailman/listinfo/python-list