This class will run a timer that checks a Queue.Queue object at a given interval. This is useful for monitoring messages between threads. You give it a callback, interval, and it does the rest: When its finds a message, your callback is fired up.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | import threading,Queue
class QueueMinder(object):
def __init__(self, msgQueue, inCallback=None, interval=1.0, doStart=False):
object.__init__(self)
self.msgQueue = msgQueue
if not inCallback: self.inCallback=self.gotMessage
else: self.inCallback=inCallback
self.interval = interval
self.progressTimer = None
if doStart:
self.startTimer()
def startTimer(self):
self.progressTimer = threading.Timer(self.interval, self._progressCheck)
self.progressTimer.start()
def stopTimer(self):
if self.progressTimer: self.progressTimer.cancel()
self.progressTimer=None
def gotMessage(self,msg):
print 'gotMessage(): msg=%s'%msg
def _progressCheck(self):
try:
while 1:
msg = self.msgQueue.get(False)
if msg: self.inCallback(msg)
except Queue.Empty:
self.startTimer()
from qt import *
class QtQueueMinder(QueueMinder, QObject):
def __init__(self, msgQueue, inCallback=None, freq=500):
QObject.__init__(self)
# the interval is in milliseconds
QueueMinder.__init__(self, msgQueue, inCallback, freq)
def startTimer(self):
if not self.progressTimer:
self.progressTimer = QTimer()
self.connect(self.progressTimer, SIGNAL("timeout()"), self._progressCheck)
self.progressTimer.start(self.interval)
def stopTimer(self):
if self.progressTimer: self.progressTimer.stop()
self.progressTimer=None
from Foundation import NSTimer
class MacQueueMinder(QueueMinder):
def runTimer(target, selector, interval):
return NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(interval,target,selector,None,True)
runTimer = staticmethod(runTimer)
def __init__(self, msgQueue, inCallback=None, freq=0.5):
# the interval is in seconds
QueueMinder.__init__(self, msgQueue, inCallback, freq)
return self
def startTimer(self):
self.progressTimer = MacQueueMinder.runTimer(self, 'progressCheck:', self.interval)
self.progressTimer.retain()
def stopTimer(self):
if self.progressTimer:
self.progressTimer.invalidate()
self.progressTimer.autorelease()
self.progressTimer = None
def progressCheck_(self,timer=None):
try:
while 1:
msg = self.msgQueue.get(False)
if msg: self.inCallback(msg)
except Queue.Empty:
pass
if __name__=='__main__':
theQueue = Queue.Queue()
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.qm =None
self.itsAllGood = True
self.start()
def run(self):
self.qm=QueueMinder(theQueue)
self.qm.startTimer()
while self.itsAllGood:
pass
tt = MyThread()
theQueue.put('How yall doin')
theQueue.put('Everybody say hey')
theQueue.put('Everybody say ho')
tt.itsAllGood = False
|
My important threads need to talk to each other, so this little abstraction comes in handy for facilitacting inter-thread communication. Note that if your calling thread was using Qt, you'd need to replace the threading.Timer with a QTimer for this to work.
UPDATE: Added subclass examples for Qt and pyobjc for Mac OS X. Each of these frameworks uses a different timer class and different methods (for instance, the interval for Qt is milliseconds, and for NSTimer its seconds). Note the code above won't compile unless you have Qt and Foundation modules present. The 2 new classes are provided as an illustration.
Optional Syntax In QueueMinder's Class Constructor. <p> Sometimes an if/else can be replaced with an 'or' for prettyness. </p>