From: Kevin A. <ka...@us...> - 2005-12-23 20:01:59
|
Update of /cvsroot/pythoncard/PythonCard/docs/html In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31660 Modified Files: timers-threads.html Log Message: converted code blocks to pre and added wx import Index: timers-threads.html =================================================================== RCS file: /cvsroot/pythoncard/PythonCard/docs/html/timers-threads.html,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** timers-threads.html 23 Dec 2005 19:46:50 -0000 1.4 --- timers-threads.html 23 Dec 2005 20:01:51 -0000 1.5 *************** *** 69,75 **** But if you haven't yet done so, add the following method code to your <span class="code">Counter</span> class:</p> ! <p class="code"> ! def on_initialize(self, event):<br /> ! print "Window opened"</p> <p>Not very significant - but do save your file, and run <span class="code"> counter.py</span>. You'll see a message on stdout when the window opens.</p> --- 69,76 ---- But if you haven't yet done so, add the following method code to your <span class="code">Counter</span> class:</p> ! <pre> ! def on_initialize(self, event): ! print "Window opened" ! </pre> <p>Not very significant - but do save your file, and run <span class="code"> counter.py</span>. You'll see a message on stdout when the window opens.</p> *************** *** 79,88 **** handler as an opportunity to set up a timer.</p> <p>So change the event handler to the following:</p> ! <p class="code"> ! def on_initialize(self, event):<br /> ! self.myTimer = timer.Timer(self.components.field1, ! -1) # create a timer<br /> ! self.myTimer.Start(5000) # launch timer, to fire ! every 5000ms (5 seconds)</p> <p>You'll also notice from the <span class="code">self.components.field1</span> that the timer is being created in respect of the <span class="code">field1</span> --- 80,88 ---- handler as an opportunity to set up a timer.</p> <p>So change the event handler to the following:</p> ! <pre> ! def on_initialize(self, event): ! self.myTimer = timer.Timer(self.components.field1, -1) # create a timer ! self.myTimer.Start(5000) # launch timer, to fire every 5000ms (5 seconds) ! </pre> <p>You'll also notice from the <span class="code">self.components.field1</span> that the timer is being created in respect of the <span class="code">field1</span> *************** *** 92,98 **** the line at the top of your <span class="code">counter.py</span> program which currently says</p> ! <p class="code">from PythonCard import model</p> <p>and change it to say</p> ! <p class="code">from PythonCard import model, timer</p> <p>Now, we have to make sure we can receive an event every time the clock 'ticks'.</p> --- 92,102 ---- the line at the top of your <span class="code">counter.py</span> program which currently says</p> ! <pre> ! from PythonCard import model ! </pre> <p>and change it to say</p> ! <pre> ! from PythonCard import model, timer ! </pre> <p>Now, we have to make sure we can receive an event every time the clock 'ticks'.</p> *************** *** 110,122 **** <p>Now, add the following method code into class <span class="code"> Counter</span>:</p> ! <p class="code"> ! def on_field1_timer(self, event):<br /> ! print "Got a timer event"<br /> ! startValue = int(self.components.field1.text)<br /> ! endValue = startValue + 10<br /> ! print "Got a timer event, value is now %d" % endValue<br /> ! self.components.field1.text = str(endValue)<br /> ! # uncomment the line below if you've already followed the 'child window' walkthrough<br /> ! #self.minimalWindow.components.field1.text = str(endValue)</p> <p><em>Note</em> - this is ugly, because there's a lot of duplicated functionality. We'll leave it to you to factorise your code appropriately, --- 114,127 ---- <p>Now, add the following method code into class <span class="code"> Counter</span>:</p> ! <pre> ! def on_field1_timer(self, event): ! print "Got a timer event" ! startValue = int(self.components.field1.text) ! endValue = startValue + 10 ! print "Got a timer event, value is now %d" % endValue ! self.components.field1.text = str(endValue) ! # uncomment the line below if you've already followed the 'child window' walkthrough ! #self.minimalWindow.components.field1.text = str(endValue) ! </pre> <p><em>Note</em> - this is ugly, because there's a lot of duplicated functionality. We'll leave it to you to factorise your code appropriately, *************** *** 165,171 **** <p>Now, add to the top of <span class="code">counter.py</span> the following statement:</p> ! <p class="code">import thread, Queue</p> <p>This will give us access to Python's thread creation/dispatch functions, ! as well as message queues</p> <h4>A Little Theory</h4> <p>I'll keep this short and sweet. Simply, the safest way for threads to --- 170,179 ---- <p>Now, add to the top of <span class="code">counter.py</span> the following statement:</p> ! <pre> ! import thread, Queue ! import wx ! </pre> <p>This will give us access to Python's thread creation/dispatch functions, ! as well as message queues and wxPython.</p> <h4>A Little Theory</h4> <p>I'll keep this short and sweet. Simply, the safest way for threads to *************** *** 207,213 **** <p>Refer back to the <span class="code">on_initialize(self, event)</span> handler above, and add the following statement:</p> ! <p class="code"> ! # Add a message queue<br /> ! self.msgQueue = Queue.Queue()</p> <p>This sticks a message queue into our <span class="code">Counter</span> window class, that will be used for communication from the thread backend to --- 215,222 ---- <p>Refer back to the <span class="code">on_initialize(self, event)</span> handler above, and add the following statement:</p> ! <pre> ! # Add a message queue ! self.msgQueue = Queue.Queue() ! </pre> <p>This sticks a message queue into our <span class="code">Counter</span> window class, that will be used for communication from the thread backend to *************** *** 216,240 **** <p>Add the following <strong>global</strong> function to your <span class="code">counter.py</span>:</p> ! <p class="code"> ! def myThread(*argtuple):<br /> ! """<br /> ! A little thread we've added<br /> ! """<br /> ! print "myThread: entered"<br /> ! q = argtuple[0]<br /> ! print "myThread: starting loop"<br /> ! x = 10<br /> ! while 1:<br /> ! time.sleep(10) # time unit is seconds<br /> ! print "myThread x=%d" % x<br /> ! q.put(str(x)) # stick something on message queue<br /> ! wx.wxWakeUpIdle() # triggers 'idle' handlers<br /> ! x += 10</p> <h4>3. Launch the Thread</h4> <p>Add the following lines at the end of your <span class="code">on_initialize</span> handler:</p> ! <p class="code"> ! # Now launch the thread<br /> ! thread.start_new_thread(myThread, (self.msgQueue,))</p> <p>Notice that we have to pass the queue object to the thread in a tuple - refer to the Python Library Reference doco for module </p> --- 225,251 ---- <p>Add the following <strong>global</strong> function to your <span class="code">counter.py</span>:</p> ! <pre> ! def myThread(*argtuple): ! """ ! A little thread we've added ! """ ! print "myThread: entered" ! q = argtuple[0] ! print "myThread: starting loop" ! x = 10 ! while True: ! time.sleep(10) # time unit is seconds ! print "myThread x=%d" % x ! q.put(str(x)) # stick something on message queue ! wx.wxWakeUpIdle() # triggers 'idle' handlers ! x += 10 ! </pre> <h4>3. Launch the Thread</h4> <p>Add the following lines at the end of your <span class="code">on_initialize</span> handler:</p> ! <pre> ! # Now launch the thread ! thread.start_new_thread(myThread, (self.msgQueue,)) ! </pre> <p>Notice that we have to pass the queue object to the thread in a tuple - refer to the Python Library Reference doco for module </p> *************** *** 246,252 **** get 'woken up'. So add the following method into your <span class="code">Counter</span> class</p> ! <p class="code"> ! def on_idle(self, event):<br /> ! print "on_idle entered" </p> <h4>5. Check the message queue and react accordingly</h4> <p>Presently, our 'idle' handler isn't very useful - but if you run --- 257,264 ---- get 'woken up'. So add the following method into your <span class="code">Counter</span> class</p> ! <pre> ! def on_idle(self, event): ! print "on_idle entered" ! </pre> <h4>5. Check the message queue and react accordingly</h4> <p>Presently, our 'idle' handler isn't very useful - but if you run *************** *** 254,267 **** So now, we'll make it do what it needs to do - reacting to events from our background thread. Replace the idle handler above with the following:</p> ! <p class="code"> ! def on_idle(self, event):<br /> ! print "on_idle entered"<br /> ! while not self.msgQueue.empty():<br /> ! # Handle messages from our thread<br /> ! msg = self.msgQueue.get()<br /> ! print "on_idle: msg='%s'" % msg<br /> ! self.components.field1.text = msg<br /> ! # uncomment the following if you've followed the 'child window' walkthrough<br /> ! #self.minimalWindow.components.field1.text = msg</p> <p>Now, we're all done. Launch your counter.py, and watch as the background thread launches, and periodically sends its messages to the user interface, --- 266,280 ---- So now, we'll make it do what it needs to do - reacting to events from our background thread. Replace the idle handler above with the following:</p> ! <pre> ! def on_idle(self, event): ! print "on_idle entered" ! while not self.msgQueue.empty(): ! # Handle messages from our thread ! msg = self.msgQueue.get() ! print "on_idle: msg='%s'" % msg ! self.components.field1.text = msg ! # uncomment the following if you've followed the 'child window' walkthrough ! #self.minimalWindow.components.field1.text = msg ! </pre> <p>Now, we're all done. Launch your counter.py, and watch as the background thread launches, and periodically sends its messages to the user interface, |