PythonCard - My app stuck when button clicked

daved170 daved170 at gmail.com
Thu May 14 08:57:02 CEST 2009


On May 13, 7:42 pm, Dave Angel <da... at ieee.org> wrote:
> daved170 wrote:
> > Hi there,
> > I'm newbie in pythonCard.
> > I have an application with 2 buttons : START , STOP
> > Start execute a while(1) loop that execute my calculations.
> > Stop suppose to raise a flag that will end that loop.
>
> > Whenever I pish the START button my GUI is stuck. the calculation
> > executes but I can't push the STOP button.
>
> > I added thread that START start a thread that execute my calculations.
> > I also added a Global variable that will hold the indication if the
> > loop should continue.
> > The problem now is that the thread ignore that variable and loop
> > forever.
>
> > Is there a simple way to make sure that the GUI won't stuck (without
> > threads)?
> > And if there isn't such way I would appriciet it very much if anyone
> > could post an example of how to make my thread read that variable
> > Thanks
> > Dave
>
> I don't know PythonCard, but most GUI's are similar enough that the
> concepts will work, even though the details differ.  I'll assume that
> PythonCard has a traditional event loop, from which all events are
> dispatched.
>
> If your loop is fairly small, then you should keep it to one thread.  
> Debugging it will usually be much easier.  The trick is to break the
> task into pieces (each piece might be once around what is now a loop),
> and invoke one piece each time the event loop empties.  I can't tell you
> how to do that without seeing your loop, but it's not usually very hard.
>
> Now, there is some way of POSTing an event to the event loop.  That puts
> the event *after* all the events that are already there, but returns
> control immediately.  So create a custom event, and POST it from the
> START button's button-pressed event.  That will fire off one "loop" of
> the special task, in other words, make one function call to your new
> function.  Then at the end of the function, POST it again, unless the
> STOP button has been pressed in the meantime.
>
> An optimization for this is to use coroutines, which are usually done
> with a generator.  It's much trickier to describe, but much easier to
> accomplish.  Roughly, you'd take your existing loop, and put a yield
> statement in it at appropriate place(s).  Then the custom event is
> simply a call to the .next() function of that generator.
>
> Now, threading isn't that tough either, depending on how much data is
> being shared between the thread and the main program.  You say that
> sharing a global flag isn't working, but it should.  So how about if you
> show us some code, and somebody'll spot the trouble.  For example, is
> the thread defined in the same module as the App?  Global only shares
> between a single module.  Another reason globals might seem to fail is
> if you tried to do mutual imports between two or more modules.  (A
> imports B, which imports A).  Sometimes that fails in mysterious ways.
>
> Make a simple (stripped) example of what you're trying, and we'll try to
> find the problem.  Without concrete code, we end up with ambiguities
> like the above usage of two different meanings for "the loop."- Hide quoted text -
>
> - Show quoted text -

Thank's Dave,
Here my code, It's a very simple app. the Start button starts a TCP/IP
communication and the Stop should dtop it and kill the client.
I'll be thankful if you'll be able to spot my mistake.
Thanks again
Dave

#Global Variable
bStopLoop = False

#Global Function
def execute(sockObj):
   while(!bStopLoop):
      str = sockObj.recv(1024)
      tmpStr = "Hello " + str
      sockObj.send(tmpStr)

#Thread handle class
class myThread(threading.Thread):
   def __init__(self,sockObj):
      threading.Thread.__init__(self)
      bStopLoop = False
      self.sockObj = sockObj

   def run(self):
      execute(self.SockObj)

# GUI
class GUI(model.Background)

   def on_Start_mouseclick(self,event):
   try:
      event.target.enable = False
      event.target.redraw()
      self.components.Start.enable = False
      self.currThread = myThread(self.sockObj)
      self.currThread.Start()
      wx.SafeYield(self)
      self.components.Start.enable = True
   except:
      .....

   def on_Stop_mouseclick(self,event):
      bStopLoop = True



More information about the Python-list mailing list