Prev: unsupported operand type(s) for %: 'NoneType' and 'tuple'
Next: ANN: WHIFF.0.7 += GAE + jQueryUI + internationalization +testdrive = (last beta?)
From: Jeff Peck on 9 Dec 2009 12:00 Philip Semanchuk wrote: > > On Dec 9, 2009, at 10:42 AM, Wanderer wrote: > >> I have a wxPython program which does some calculations and displays >> the results. During these calculations if I click the mouse inside the >> dialog the program locks up. If I leave the dialog alone the process >> completes fine. I have tried running the function from a separate >> dialog with Show Modal and I have tried using SetEvtHandlerEnabled all >> to no avail. The program is long and occupies several files so I won't >> show the whole thing but here is the calculation part. How do I block >> events? > > > Hi Wanderer, > I don't have a solution for you but I have three suggestions. > > First, your program shouldn't be locking up just because you clicked > on it. IMO that's the real problem, and discarding events is just a > band-aid to cover it up. Nevertheless, sometimes a band-aid is an > appropriate solution and you're the best judge of that. > > Second, the wxPython mailing list would be a better place for this > question. > > Third, if you can't seem to resolve the problem, try paring it down to > a minimal example that reproduces the problem. It's difficult to offer > suggestions when we can't see the whole code or try the sample code > ourselves. > > > Good luck > Philip Wanderer, I agree with Philip. You probably want your calculation code in a separate thread. I'd advise against this, but if you're just looking for a bandaid you could try creating an event handler to catch the mouse clicks and simply call event.Skip(). If you do this, you might have to introduce a flag that gets set to True only during your calculation, and then your event hander could look something like this: def OnMouseClick(self, event): # Only skip mouse click event if calculating if self.busy: event.Skip() Jeff
From: Dave Angel on 9 Dec 2009 17:10 Wanderer wrote: > <snip> > > Found another strange bug (Strange to me, anyway). int(0.8 * 10.0) 7. Had to change the code to int(0.8 * 10.0 + 0.0001). > > > Floating point is intrinsically imprecise. The value 0.8 cannot be exactly represented in IEEE fp notation (binary). One answer is to round() the result before converting to int. DaveaA
From: Frank Millman on 10 Dec 2009 01:21 Wanderer wrote: >I have a wxPython program which does some calculations and displays > the results. During these calculations if I click the mouse inside the > dialog the program locks up. If I leave the dialog alone the process > completes fine. I have tried running the function from a separate > dialog with Show Modal and I have tried using SetEvtHandlerEnabled all > to no avail. The program is long and occupies several files so I won't > show the whole thing but here is the calculation part. How do I block > events? > I also need to block events in my wxPython app, though the time duration is very short. I have a separate thread that sends notification of gui events to a server, and waits for a response. I do not want the user to do anything until the response is received. I use threading.Event() for this - import threading event_waiting = threading.Event() event_waiting.set() # set event to True In the gui thread, when I want to block, I have this - event_waiting.clear() # set event to False event_waiting.wait() # block until event becomes True In the worker thread, when the response has been received and acted upon, I have - event_waiting.set() # set event to True, which unblocks the gui thread HTH Frank Millman
From: Frank Millman on 10 Dec 2009 09:01 Stephen Hansen wrote: > On Wed, Dec 9, 2009 at 10:21 PM, Frank Millman <frank(a)chagford.com> wrote: > >> I also need to block events in my wxPython app, though the time duration >> is >> very short. I have a separate thread that sends notification of gui >> events >> to a server, and waits for a response. I do not want the user to do >> anything until the response is received. >> > I don't think "blocking" events is the right way to think about this. > > If you need to halt new input for some reason (bearing in mind that its > best > to run such things in a background task, but yes, sometimes blocking the > UI > is important), then there's a couple ways to go about it. But trying to > mess > with the event loop isn't it. In fact my method does not work. All that happens is that the events are queued, and as soon as I release the lock the events are processed in a bunch. Not clever :-( > > First, you always want a visual indicator-- use SetCursor on your top > level > window to set a busy cursor. You never want any sort of block-ish action > to > happen without the user being able to see "something is going on"; if its > more then a second or so I /really/ think you should throw up a progress > indicator dialog, even if its an infinate one. > Agreed. > To actually 'block' the events themselves, you can just call > wnd.Enable(False). Just be sure to Enable(True) when you want to process > stuff again. This may work for the OP, but would not really work for me, because it changes the visual appearance of all the controls. In my case the time duration for blocking is usually very short, so it could result in flicker. > > Another approach is to use wnd.CaptureMouse() on a particular control > which > doesn't really respond to anything. Just be sure to ReleaseMouse() later > and > follow the instructions in the docs about capturing that cancel-capture > event. > I like this. Unfortunately it does not block keyboard input. However, I have a keyboard event handler on virtually all my controls, so it should be easy to set a flag and tell it to ignore keystrokes while in a 'blocked' state. > HTH, It certainly does - thanks. Frank
From: Frank Millman on 11 Dec 2009 02:00
Stephen Hansen wrote: > > Well if you have a legitimate case for pre-empting the event loop with > these > periodic regular short blocking moments (it seems you may), I think what > you > want to do is overwrite FilterEvent on your App object. You can then make > that flag something you set on the app, and while it's true, returning > False > (or True, I really don't know the differenced between telling wx 'Ok, I > processed this event you can ignore it' and 'Ok, I'm not going to process > this event and neither should you'). Otherwise, return -1. > This works beautifully - thanks, Stephen. As you say, the difference between returning True or False is not clear, but in practice I found that I had to return True - then all mouse and keyboard activity is blocked. There is another step required, which I did not find in the docs, but found in help(wx.App.FilterEvent). If you override FilterEvent, you also have to call SetCallFilterEvent(True) on the App object when you want it to be called, and set it back to False when finished. This is handy, as it avoids the overhead of calling it when you don't need it. In fact, as I am writing this, I realise that I don't need a flag at all. I just override FilterEvent, and return True. Then when I want to block, I call SetCallFilterEvent(True), and when I want to stop, I call SetCallFilterEvent(False). This is very useful. Thanks again. Frank |