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

Reply via email to