On May 14, 2:37 pm, Dave Angel <da...@ieee.org> wrote: > daved170 wrote: > > On May 13, 7:42 pm, Dave Angel <da...@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 =alse > > > #Global Function > > def execute(sockObj): > > while(!bStopLoop): > > str =ockObj.recv(1024) > > tmpStr =Hello " + str > > sockObj.send(tmpStr) > > > #Thread handle class > > class myThread(threading.Thread): > > def __init__(self,sockObj): > > threading.Thread.__init__(self) > > bStopLoop =alse > > self.sockObj =ockObj > > > def run(self): > > execute(self.SockObj) > > > # GUI > > class GUI(model.Background) > > > def on_Start_mouseclick(self,event): > > try: > > event.target.enable =alse > > event.target.redraw() > > self.components.Start.enable =alse > > self.currThread =yThread(self.sockObj) > > self.currThread.Start() > > wx.SafeYield(self) > > self.components.Start.enable =rue > > except: > > ..... > > > def on_Stop_mouseclick(self,event): > > bStopLoop =rue > > In the two methods that try to change bStopLoop, you don't declare it > global. Add the line "global bStopLoop" to beginning of both > > on_Start_mouseclick() and on_Stop_mouseclick(), and (my preference) to > function execute() > > The semantics of global versus local variables for non-nested > functions/methods is roughly: if a function or method assigns to a name, > it's taken to be a local, unless it's explicitly declared as global.- Hide > quoted text - > > - Show quoted text -
Thanks Dave. It works! It solved that problem. Now all i need is to stop the socket in a way that whenever I push the Start button again my app won't raise network connectio, but I think I'll handle that by myself. Thank's again Dave. -- http://mail.python.org/mailman/listinfo/python-list