Hello, I have started a project using Tkinter. The application performs some regular checks in a thread and updates Canvas components. I have observed that sometimes the application hangs when it is about to call canvas.itemconfig() when the thread is about to terminate in the next loop.
Experimenting with this problem for a while, I have compiled a little example which always reproduces the problem. Commenting out the line 52 (before canvas.itemconfig()), the example always finishes all right, having the delay there, it hangs. I would like to ask if you could have a look at the snippet in the attachment and tell me if that is actually me doing something wrong or indeed Tkinter thread safety problem and what the workaround could be. Could you please also comment on wxPython thread safety? I am using: Python 2.5.4 (r254:67916, Feb 17 2009, 20:16:45) [GCC 4.3.3] 2.6.26-1-amd64 #1 SMP Fri Mar 13 19:34:38 UTC 2009 x86_64 GNU/Linux Thanks in advance, Zdenek
import threading, time from Tkinter import * class MyThread(threading.Thread): def __init__(self, action): self.action = action threading.Thread.__init__(self) self.__stopFlag = False def run(self): print "thread started." while True: if self.__stopFlag: break time.sleep(0.2) if self.__stopFlag: break print "thread loop running ..." self.action() print "thread loop finished, sleeping ..." print "thread finished." def setStop(self): self.__stopFlag = True # class MyThread ------------------------------------------------------------ class Application(object): def __init__(self, tkRoot): self.tkRoot = tkRoot self.tkRoot.protocol("WM_DELETE_WINDOW", self.__onClose) self.canvas = Canvas(self.tkRoot, bg = "white") self.canvas.pack(expand = YES, fill = BOTH) self.curCol = "red" self.boxId = self.canvas.create_rectangle(50, 50, 120, 120, width = 1, fill = self.curCol) self.__thChecker = MyThread(self.toggleColor) self.__thChecker.start() def toggleColor(self): if self.curCol == "red": self.curCol = "green" else: self.curCol = "red" # delay here causes self.canvas.itemconfig() to hang on # self.__thChecker.join() time.sleep(2) self.canvas.itemconfig(self.boxId, fill = self.curCol) def __onClose(self): print "setting stop flag ..." self.__thChecker.setStop() print "terminating thread ..." self.__thChecker.join() if self.__thChecker.isAlive(): print "could not stop the thread." else: print "thread stopped successfully." self.tkRoot.destroy() print "application shut." # class Application --------------------------------------------------------- tkRoot = Tk() tkRoot.geometry("200x200+200+200") Application(tkRoot) tkRoot.mainloop()
-- http://mail.python.org/mailman/listinfo/python-list