<div>Thanks a lot Laszlo Nagy,</div>
<div> </div>
<div>I used the following and it worked.</div>
<div> </div>
<div><font face="verdana" color="#3333ff">import time<br>from threading import *<br>import wx</font></div>
<p><font face="verdana" color="#3333ff"># Button definitions<br>ID_START = wx.NewId()<br>ID_STOP = wx.NewId()</font></p>
<p><font face="verdana" color="#3333ff"># Define notification event for thread completion<br>EVT_RESULT_ID = wx.NewId()</font></p>
<p><font face="verdana" color="#3333ff">def EVT_RESULT(win, func):<br> """Define Result Event."""<br> win.Connect(-1, -1, EVT_RESULT_ID, func)</font></p>
<p><font face="verdana" color="#3333ff">class ResultEvent(wx.PyEvent):<br> """Simple event to carry arbitrary result data."""<br> def __init__(self, data):<br> """Init Result Event."""
<br> wx.PyEvent.__init__(self)<br> self.SetEventType(EVT_RESULT_ID)<br> self.data = data</font></p>
<p><font face="verdana" color="#3333ff"># Thread class that executes processing<br>class WorkerThread(Thread):<br> """Worker Thread Class."""<br> def __init__(self, notify_window):<br>
"""Init Worker Thread Class."""<br> Thread.__init__(self)<br> self._notify_window = notify_window<br> self._want_abort = 0<br> # This starts the thread running on creation, but you could
<br> # also make the GUI thread responsible for calling this<br> self.start()</font></p>
<p><font face="verdana" color="#3333ff"> def run(self):<br> """Run Worker Thread."""<br> # This is the code executing in the new thread. Simulation of<br> # a long process (well, 10s here) as a simple loop - you will
<br> # need to structure your processing so that you periodically<br> # peek at the abort variable<br> for i in range(10):<br> time.sleep(1)<br> if self._want_abort:<br> # Use a result of None to acknowledge the abort (of
<br> # course you can use whatever you'd like or even<br> # a separate event type)<br> wx.PostEvent(self._notify_window, ResultEvent(None))<br> return<br> # Here's where the result would be returned (this is an
<br> # example fixed result of the number 10, but it could be<br> # any Python object)<br> wx.PostEvent(self._notify_window, ResultEvent(10))</font></p>
<p><font face="verdana" color="#3333ff"> def abort(self):<br> """abort worker thread."""<br> # Method for use by main thread to signal an abort<br> self._want_abort = 1
</font></p>
<p><font face="verdana" color="#3333ff"># GUI Frame class that spins off the worker thread<br>class MainFrame(wx.Frame):<br> """Class MainFrame."""<br> def __init__(self, parent, id):<br>
"""Create the MainFrame."""<br> wx.Frame.__init__(self, parent, id, 'Thread Test')</font></p>
<p><font face="verdana" color="#3333ff"> # Dumb sample frame with two buttons<br> wx.Button(self, ID_START, 'Start', pos=(0,0))<br> wx.Button(self, ID_STOP, 'Stop', pos=(0,50))<br>
self.status = wx.StaticText(self, -1, '', pos=(0,100))</font></p>
<p><font face="verdana" color="#3333ff"> self.Bind(wx.EVT_BUTTON, self.OnStart, id=ID_START)<br> self.Bind(wx.EVT_BUTTON, self.OnStop, id=ID_STOP)</font></p>
<p><font face="verdana" color="#3333ff"> # Set up event handler for any worker thread results<br> EVT_RESULT(self,self.OnResult)</font></p>
<p><font face="verdana" color="#3333ff"> # And indicate we don't have a worker thread yet<br> self.worker = None</font></p>
<p><font face="verdana" color="#3333ff"> def OnStart(self, event):<br> """Start Computation."""<br> # Trigger the worker thread unless it's already busy<br> if not
self.worker:<br> self.status.SetLabel('Starting computation')<br> self.worker = WorkerThread(self)</font></p>
<p><font face="verdana" color="#3333ff"> def OnStop(self, event):<br> """Stop Computation."""<br> # Flag the worker thread to stop if running<br> if self.worker:<br>
self.status.SetLabel('Trying to abort computation')<br> self.worker.abort()</font></p>
<p><font face="verdana" color="#3333ff"> def OnResult(self, event):<br> """Show Result status."""<br> if event.data is None:<br> # Thread aborted (using our convention of None return)
<br> self.status.SetLabel('Computation aborted')<br> else:<br> # Process results here<br> self.status.SetLabel('Computation Result: %s' % event.data)<br> # In either event, the worker is done
<br> self.worker = None</font></p>
<p><font face="verdana" color="#3333ff">class MainApp(wx.App):<br> """Class Main App."""<br> def OnInit(self):<br> """Init Main App."""<br>
self.frame = MainFrame(None, -1)<br> self.frame.Show(True)<br> self.SetTopWindow(self.frame)<br> return True</font></p>
<p><font face="verdana" color="#3333ff">if __name__ == '__main__':<br> app = MainApp(0)<br> app.MainLoop()<br></font></p>
<div><br>Thanks & Regards,</div>
<div>Tarun<br> </div>
<div><span class="gmail_quote">On 11/13/07, <b class="gmail_sendername">Laszlo Nagy</b> <<a href="mailto:gandalf@shopzeus.com">gandalf@shopzeus.com</a>> wrote:</span>
<blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid">tarun írta:<br>> Hi Laszlo Nagy,<br>><br>> Thanks a lot.<br>> But the issue over here is that how will the child thread acknowledge
<br>> the main thread that it has completed its task. For this I'll have to<br>> set some flag in the child thread and poll for it in the main thread.<br>> This will create a problem.<br>What kind of problem, can you explain? Supposing your child (worker)
<br>thread created the output, I would do it this way (untested):<br><br>class Child(threading.Thread):<br> def __init__(self,output):<br> self.stop_requested = threading.Event()<br> self.stopped = threading.Event
()<br> self.output = output<br> ....<br><br> def run(self):<br> try:<br> while not self.stop_requested.isSet():<br> # put your algorithm here<br> ....<br> # but check periodically if you need to abort the job.
<br> if self.stop_requested.isSet():<br> break<br> ...<br> # when you have data, put into the output queue<br> self.output.put( your_output )<br> finally:
<br> self.stopped.set()<br><br><br>-- And then, from the main thread, create the worker:<br><br>self.queue = Queue()<br>self.child = Child(self.queue)<br><br>-- wxApp.OnIdle:<br><br>if not self.queue.empty():<br> data =
self.queue.get()<br> # display your data here, for example add to a text control.<br><br>if self.child.stopped.isSet():<br> add_log("Job compete") # tell the user what is going on<br><br>And finally, you can have a button for stopping the script:
<br><br>def OnClick(self,event):<br> self.child.stop_requested.set()<br> add_log("stopping worker thread....") # tell the user what is going on<br><br>> Any alternatives??<br>First you should tell us what is the problem with using two threads.
<br><br>Regards,<br><br> Laszlo<br><br><br><br><br><br><br></blockquote></div><br>