Re: wxPython fast and slow
iu2 writes: > A question about CallAfter: As I understand, this function is intended > to be used from within threads, where it queues the operation to be > performed in the GUI queue. I agree with the second half of the sentence but not the first. CallAfter is intended to queue up a delayed call (via the GUI queue), but it can be used anywhere you wish that behavior. Yes, it's also one of the very few functions that can be called from a thread other than the GUI thread, but it works just as well from the GUI thread. Or to quote its docstring: Call the specified function after the current and pending event handlers have been completed. This is also good for making GUI method calls from non-GUI threads. Any extra positional or keyword args are passed on to the callable when it is called. > How does it work in this situation? Does it queue the opreation for > some idle time or does it perform it right away? You can actually see the source in _core.py in your wx installation. It always executes via a wx.PostEvent call. > And another question, if I may, I used to make tight loops in windows > API, planting inside them a command that processes messages from the > GUI queue and returns when no more messages exists. Something like > this: > > loop { > operations > process_gui_messages > } > > The loop ran quickly and the GUI remained responsive during the loop. > I did it on window API using a function I defined similar to this one: I don't think there's much difference in the above and doing your operations during one of the events. In both cases "operations" is going to block any further event processing so cannot be lengthy or the GUI will feel unresponsive. "Lengthy" varies but I'd certainly put it in the neighborhood of small fractions of a second. Your original code took almost 2 seconds for the "operations" part (before getting back to processing GUI messages through the main loop), which certainly seems too long. > void ProcessMessages() > { > while (PeekMessage()) { > TranslateMessage(..); > DispatchMessage(..); > } > } Not quite positive, but if you're talking about implementing this as a nested dispatch loop (e.g., called from within an existing event), you can do that via wxYield. Of course, as with any nested event loop processing, you have to be aware of possible reentrancy issues. > This technique is not good for long loops, where the user may activate > other long GUI opreations during the tight loop and make a mess. > But it carries out the job well where during the time of the loop the > user may only access to certain features, such as pressing a button to > cancel the operation, operating the menu to exit the program, etc. > This scheme saves some state-machine code that is required when using > event-based programming. Maybe - for my own part, I'm not completely convinced and tend to far prefer avoiding nested event loop dispatching. There are some times when it might be unavoidable, but I tend to find it indicative that I might want to re-examine what I am doing. It seems to me that as long as you have to keep the "operations" step of your loop small enough, you have to be able to divide it up. So you'll need some state no matter what to be able to work through each stage of the overall "operations" in between calls to process the GUI. At that point, whether it's a local variable within the scope of the looping code, or just some instance variables in the object handling the event loop seems about the same amount of state management. For example, in your original code you could probably consider the generator and/or 'x' your local state. But the current step in the movement could just as easily be an instance variable. > Does wxPython have something like ProcessMessages? If you just mean a way to process pending messages wxYield may be sufficient. If you want to take over the primary dispatch loop for the application, normally that has been handed off to wxWidgets via wxApp.MainLoop. However, I believe you can build your own main dispatch loop if you want, as there are functions in wxApp like ProcessPendingEvents, Pending, Dispatch and so on. You may need to explicitly continue to support Idle events in your own loop if desired. If you need to get into more details, it's probably better dealt with on the wxPython mailing list. -- David -- http://mail.python.org/mailman/listinfo/python-list
Re: wxPython fast and slow
On Mar 9, 4:18 am, David Bolen wrote: > iu2 writes: > > Then even a time.sleep() or plain loop isn't sufficient since each may > have additional latencies depending on load. You will probably need > to query a system clock of some type to verify when your interval has > passed. > > You might also try an idle event, implementing your own timer (using > whatever call gives you the best resolution on your platform), and > just ignoring idle events that occur more frequently than the timing > you want. Just remember to always request a new event. You could do > the same thing with CallAfter as well, just reschedule a new one if > the current one is faster than your preferred interval. > > -- David Thanks, I need to give it a try. > > Except that CallAfter passed control back through the event loop which is > crucial for your GUI to appear responsive in other ways. A question about CallAfter: As I understand, this function is intended to be used from within threads, where it queues the operation to be performed in the GUI queue. But in this example there are no other threads except for the GUI thread itself, from which CallAfter is called. How does it work in this situation? Does it queue the opreation for some idle time or does it perform it right away? I thought that it probably performs it immediately in this case so it is exactly like calling the operation directly. And another question, if I may, I used to make tight loops in windows API, planting inside them a command that processes messages from the GUI queue and returns when no more messages exists. Something like this: loop { operations process_gui_messages } The loop ran quickly and the GUI remained responsive during the loop. I did it on window API using a function I defined similar to this one: void ProcessMessages() { while (PeekMessage()) { TranslateMessage(..); DispatchMessage(..); } } This technique is not good for long loops, where the user may activate other long GUI opreations during the tight loop and make a mess. But it carries out the job well where during the time of the loop the user may only access to certain features, such as pressing a button to cancel the operation, operating the menu to exit the program, etc. This scheme saves some state-machine code that is required when using event-based programming. Does wxPython have something like ProcessMessages? Thanks -- http://mail.python.org/mailman/listinfo/python-list
Re: wxPython fast and slow
On Mar 8, 12:35 pm, iu2 wrote: > On Mar 8, 1:42 pm, Carl Banks wrote: > > > > > On Mar 8, 1:52 am, iu2 wrote: > > > > On Mar 6, 6:52 pm, Mike Driscoll wrote: > > > > > ... > > > > Can you post a sample application so we can try to figure out what's > > > > wrong? You might also cross-post this to thewxPythonmailing list. > > > > They might know. > > > > > Mike- Hide quoted text - > > > > > - Show quoted text - > > > > Hi, thanks for your reply > > > > Here is a sample application: > > > > -- > > > > import wx > > > import time > > > > class My_frame(wx.Frame): > > > def __init__(self): > > > wx.Frame.__init__(self, None, -1, 'Moving panel') > > > self.surface = p = wx.Panel(self, size=(300, 130)) > > > self.square = wx.Panel(p, -1, size=(100, 100), pos=(0, 30)) > > > self.square.Bind(wx.EVT_PAINT, self.on_paint_square) > > > > btn_move = wx.Button(p, -1, 'Move panel', pos=(0, 0)) > > > self.Bind(wx.EVT_BUTTON, self.move_panel, btn_move) > > > > self.Fit() > > > > def move_panel(self, evt): > > > def gen(): > > > for x in range(200): > > > yield x > > > for x in range(200, 0, -1): > > > yield x > > > for x in gen(): > > > self.square.SetPosition((x, 30)) > > > time.sleep(0.005) > > > > def on_paint_square(self, evt): > > > square = evt.GetEventObject() > > > dc = wx.BufferedPaintDC(square) > > > dc.Pen = wx.Pen('blakc', 2) > > > dc.Brush = wx.Brush('light blue') > > > dc.DrawRectangle(0, 0, *square.GetSize()) > > > > app = wx.PySimpleApp() > > > My_frame().Show() > > > app.MainLoop() > > > > -- > > > > Press the button and the panel moves to the right and then back to the > > > left. > > > While PyScripter is running the panel moves at a certain speed. You > > > can run the application from the Windows explorer with the same speed. > > > You don't need to run it from PyScripter. > > > When PyScripter is closed, the application runs much less quickly. > > > I experienced this on two PC-s. > > > Maybe this behavior is not even related towxPythonbut to the sleep > > > command. I don't know... > > > It's not a good idea to call time.sleep inside a loop inside an event > > handler, which is what you are doing here. > > > wx has a mechanism to call some sort of callback at timed intervals. > > (I don't know what it is but I know it has one.) Instead of animating > > the box move inside the button callback, have it request that a > > callback be called after x seconds pass, and draw a single frame > > inside that callback. Then invoke it again until you're done drawing. > > > Here's a rough idea of what that might look like: > > > class My_frame(wx.Frame): > > > # ... among other things ... > > > def move_panel(self,evt): > > self.square_pos = 0 > > wx.set_timed_callback_of_some_sort( > > self.draw_frame,0.005) > > > def draw_frame(self): > > self.square.SetPosition((self.square_pos, 30)) > > self.square_pos += 1 > > if self.square_pos < 200: > > wx.set_timed_callback_of_some_sort( > > self.draw_frame,0.005) > > > As for why it works fine in PyScripter but not when started from > > Explorer, well, let's just say that when you abuse callbacks like you > > did, you shouldn't expect reasonable behavior. > > > Carl Banks > > Hi, > > Here is the timer version. It works even more slowly, even with > PyScripter active: > > -- > import wx > import time > > class My_frame(wx.Frame): > def __init__(self): > wx.Frame.__init__(self, None, -1, 'Moving panel') > self.surface = p = wx.Panel(self, size=(300, 130)) > self.square = wx.Panel(p, -1, size=(100, 100), pos=(0, 30)) > self.square.Bind(wx.EVT_PAINT, self.on_paint_square) > > btn_move = wx.Button(p, -1, 'Move panel', pos=(0, 0)) > self.Bind(wx.EVT_BUTTON, self.move_panel, btn_move) > > self.Fit() > > def on_paint_square(self, evt): > square = evt.GetEventObject() > dc = wx.BufferedPaintDC(square) > dc.Pen = wx.Pen('blakc', 2) > dc.Brush = wx.Brush('light blue') > dc.DrawRectangle(0, 0, *square.GetSize()) > > def move_panel(self, evt): > def gen(): > for x in range(200): > yield x > for x in range(200, 0, -1): > yield x > self.track = gen() > self.timer = wx.Timer(self) > self.Bind(wx.EVT_TIMER, self.on_timer_square, self.timer) > self.timer.Start(milliseconds=1) > > def on_timer_square(self, evt): > try: > x = self.track.next() > self.square.SetPosition((x, 30)) > e
Re: wxPython fast and slow
iu2 writes: > Indeed, but I don't think the CallAfter is necessary. I could just as > well remove the time.sleep in the original code. I could also make a > tight loop to replace time.sleep > for i in range(100): pass > and tune it to fit the speed I need. Except that CallAfter passed control back through the event loop which is crucial for your GUI to appear responsive in other ways. > I haven't mention this, but I actually want something to be the same > speed on different PC-s. So a timer seems to fit in. Then even a time.sleep() or plain loop isn't sufficient since each may have additional latencies depending on load. You will probably need to query a system clock of some type to verify when your interval has passed. > I just can't make it work. > Using wx.Timer is too slow. > Using time.sleep is fast with PyScripter active, and slow when it is > closed. I have to admit to thinking that perhaps you're trying to operate too quickly if you need better resolution than wx.Timer. Most screen operations don't have to appear that frequently to still appear smooth, but that's your call. Of course, even wx.Timer may be subject to other latencies if the system or your application is busy with other events, so it depends on how critical precise your timing needs to be. You might also try an idle event, implementing your own timer (using whatever call gives you the best resolution on your platform), and just ignoring idle events that occur more frequently than the timing you want. Just remember to always request a new event. You could do the same thing with CallAfter as well, just reschedule a new one if the current one is faster than your preferred interval. -- David -- http://mail.python.org/mailman/listinfo/python-list
Re: wxPython fast and slow
On Mar 9, 12:44 am, Scott David Daniels wrote: > iu2 wrote: > > Here is the timer version. It works even more slowly, even with > > PyScripter active: ... > > > I actually tried this one first. Due to the slow speed I changed to > > looping inside the event. > > I don't understand why it takes so long to move that square with > > wx.Timer set to 1 ms interval. Perhaps its minimum interval is > > actually 10 ms (as in Windows) so 100 steps really take 1 second. > > But in that case, I really want to move the square in a tight loop > > inside the wx.EVT_BUTTON event. > > > So allow me to rephrase my question: > > Is there a way to move that square quickly and smoothly? Should 400 > > one-pixel moves should take so long on a 2.8 GHz core duo? > > > There is certainly something wrong in the code I wrote which I need > > your help to figure out. > > Can it be related to recurring paint events? If so how should I change > > the code? > > > Thanks > > Here is a too-fast version you could fiddle around with: > > import wx > > class My_frame(wx.Frame): > def __init__(self): > wx.Frame.__init__(self, None, -1, 'Moving panel') > self.surface = p = wx.Panel(self, size=(300, 130)) > self.square = wx.Panel(p, -1, size=(100, 100), pos=(0, 30)) > self.square.Bind(wx.EVT_PAINT, self.on_paint_square) > > btn_move = wx.Button(p, -1, 'Move panel', pos=(0, 0)) > self.Bind(wx.EVT_BUTTON, self.startcalls, btn_move) > self.Fit() > > def startcalls(self, evt=None): > def gen(): > for x in range(200): > yield x > for x in range(200, 0, -1): > yield x > self.track = gen().next > wx.CallAfter(self.stepcall) > > def stepcall(self, evt=None): > try: > x = self.track() > except StopIteration: > pass > else: > self.square.SetPosition((x, 30)) > wx.CallAfter(self.stepcall) > > def on_paint_square(self, evt): > square = evt.GetEventObject() > dc = wx.BufferedPaintDC(square) > dc.Pen = wx.Pen('black', 2) > dc.Brush = wx.Brush('light blue') > dc.DrawRectangle(0, 0, *square.GetSize()) > > if __name__ == '__main__': > app = wx.PySimpleApp() > My_frame().Show() > app.MainLoop() Indeed, but I don't think the CallAfter is necessary. I could just as well remove the time.sleep in the original code. I could also make a tight loop to replace time.sleep for i in range(100): pass and tune it to fit the speed I need. I haven't mention this, but I actually want something to be the same speed on different PC-s. So a timer seems to fit in. I just can't make it work. Using wx.Timer is too slow. Using time.sleep is fast with PyScripter active, and slow when it is closed. -- http://mail.python.org/mailman/listinfo/python-list
Re: wxPython fast and slow
iu2 wrote: Here is the timer version. It works even more slowly, even with PyScripter active: ... I actually tried this one first. Due to the slow speed I changed to looping inside the event. I don't understand why it takes so long to move that square with wx.Timer set to 1 ms interval. Perhaps its minimum interval is actually 10 ms (as in Windows) so 100 steps really take 1 second. But in that case, I really want to move the square in a tight loop inside the wx.EVT_BUTTON event. So allow me to rephrase my question: Is there a way to move that square quickly and smoothly? Should 400 one-pixel moves should take so long on a 2.8 GHz core duo? There is certainly something wrong in the code I wrote which I need your help to figure out. Can it be related to recurring paint events? If so how should I change the code? Thanks Here is a too-fast version you could fiddle around with: import wx class My_frame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, 'Moving panel') self.surface = p = wx.Panel(self, size=(300, 130)) self.square = wx.Panel(p, -1, size=(100, 100), pos=(0, 30)) self.square.Bind(wx.EVT_PAINT, self.on_paint_square) btn_move = wx.Button(p, -1, 'Move panel', pos=(0, 0)) self.Bind(wx.EVT_BUTTON, self.startcalls, btn_move) self.Fit() def startcalls(self, evt=None): def gen(): for x in range(200): yield x for x in range(200, 0, -1): yield x self.track = gen().next wx.CallAfter(self.stepcall) def stepcall(self, evt=None): try: x = self.track() except StopIteration: pass else: self.square.SetPosition((x, 30)) wx.CallAfter(self.stepcall) def on_paint_square(self, evt): square = evt.GetEventObject() dc = wx.BufferedPaintDC(square) dc.Pen = wx.Pen('black', 2) dc.Brush = wx.Brush('light blue') dc.DrawRectangle(0, 0, *square.GetSize()) if __name__ == '__main__': app = wx.PySimpleApp() My_frame().Show() app.MainLoop() -- http://mail.python.org/mailman/listinfo/python-list
Re: wxPython fast and slow
On Mar 8, 1:42 pm, Carl Banks wrote: > On Mar 8, 1:52 am, iu2 wrote: > > > > > On Mar 6, 6:52 pm, Mike Driscoll wrote: > > > > ... > > > Can you post a sample application so we can try to figure out what's > > > wrong? You might also cross-post this to thewxPythonmailing list. > > > They might know. > > > > Mike- Hide quoted text - > > > > - Show quoted text - > > > Hi, thanks for your reply > > > Here is a sample application: > > > -- > > > import wx > > import time > > > class My_frame(wx.Frame): > > def __init__(self): > > wx.Frame.__init__(self, None, -1, 'Moving panel') > > self.surface = p = wx.Panel(self, size=(300, 130)) > > self.square = wx.Panel(p, -1, size=(100, 100), pos=(0, 30)) > > self.square.Bind(wx.EVT_PAINT, self.on_paint_square) > > > btn_move = wx.Button(p, -1, 'Move panel', pos=(0, 0)) > > self.Bind(wx.EVT_BUTTON, self.move_panel, btn_move) > > > self.Fit() > > > def move_panel(self, evt): > > def gen(): > > for x in range(200): > > yield x > > for x in range(200, 0, -1): > > yield x > > for x in gen(): > > self.square.SetPosition((x, 30)) > > time.sleep(0.005) > > > def on_paint_square(self, evt): > > square = evt.GetEventObject() > > dc = wx.BufferedPaintDC(square) > > dc.Pen = wx.Pen('blakc', 2) > > dc.Brush = wx.Brush('light blue') > > dc.DrawRectangle(0, 0, *square.GetSize()) > > > app = wx.PySimpleApp() > > My_frame().Show() > > app.MainLoop() > > > -- > > > Press the button and the panel moves to the right and then back to the > > left. > > While PyScripter is running the panel moves at a certain speed. You > > can run the application from the Windows explorer with the same speed. > > You don't need to run it from PyScripter. > > When PyScripter is closed, the application runs much less quickly. > > I experienced this on two PC-s. > > Maybe this behavior is not even related towxPythonbut to the sleep > > command. I don't know... > > It's not a good idea to call time.sleep inside a loop inside an event > handler, which is what you are doing here. > > wx has a mechanism to call some sort of callback at timed intervals. > (I don't know what it is but I know it has one.) Instead of animating > the box move inside the button callback, have it request that a > callback be called after x seconds pass, and draw a single frame > inside that callback. Then invoke it again until you're done drawing. > > Here's a rough idea of what that might look like: > > class My_frame(wx.Frame): > > # ... among other things ... > > def move_panel(self,evt): > self.square_pos = 0 > wx.set_timed_callback_of_some_sort( > self.draw_frame,0.005) > > def draw_frame(self): > self.square.SetPosition((self.square_pos, 30)) > self.square_pos += 1 > if self.square_pos < 200: > wx.set_timed_callback_of_some_sort( > self.draw_frame,0.005) > > As for why it works fine in PyScripter but not when started from > Explorer, well, let's just say that when you abuse callbacks like you > did, you shouldn't expect reasonable behavior. > > Carl Banks Hi, Here is the timer version. It works even more slowly, even with PyScripter active: -- import wx import time class My_frame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, 'Moving panel') self.surface = p = wx.Panel(self, size=(300, 130)) self.square = wx.Panel(p, -1, size=(100, 100), pos=(0, 30)) self.square.Bind(wx.EVT_PAINT, self.on_paint_square) btn_move = wx.Button(p, -1, 'Move panel', pos=(0, 0)) self.Bind(wx.EVT_BUTTON, self.move_panel, btn_move) self.Fit() def on_paint_square(self, evt): square = evt.GetEventObject() dc = wx.BufferedPaintDC(square) dc.Pen = wx.Pen('blakc', 2) dc.Brush = wx.Brush('light blue') dc.DrawRectangle(0, 0, *square.GetSize()) def move_panel(self, evt): def gen(): for x in range(200): yield x for x in range(200, 0, -1): yield x self.track = gen() self.timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.on_timer_square, self.timer) self.timer.Start(milliseconds=1) def on_timer_square(self, evt): try: x = self.track.next() self.square.SetPosition((x, 30)) except StopIteration: self.timer.Stop() app = wx.PySimpleApp() My_frame().Show() app.MainLoop() - I actually tried this one first. Due to the slow speed I changed to looping inside the eve
Re: wxPython fast and slow
On Mar 8, 3:52 am, iu2 wrote: > On Mar 6, 6:52 pm, Mike Driscoll wrote: > > > ... > > Can you post a sample application so we can try to figure out what's > > wrong? You might also cross-post this to thewxPythonmailing list. > > They might know. > > > Mike- Hide quoted text - > > > - Show quoted text - > > Hi, thanks for your reply > > Here is a sample application: > > -- > > import wx > import time > > class My_frame(wx.Frame): > def __init__(self): > wx.Frame.__init__(self, None, -1, 'Moving panel') > self.surface = p = wx.Panel(self, size=(300, 130)) > self.square = wx.Panel(p, -1, size=(100, 100), pos=(0, 30)) > self.square.Bind(wx.EVT_PAINT, self.on_paint_square) > > btn_move = wx.Button(p, -1, 'Move panel', pos=(0, 0)) > self.Bind(wx.EVT_BUTTON, self.move_panel, btn_move) > > self.Fit() > > def move_panel(self, evt): > def gen(): > for x in range(200): > yield x > for x in range(200, 0, -1): > yield x > for x in gen(): > self.square.SetPosition((x, 30)) > time.sleep(0.005) > > def on_paint_square(self, evt): > square = evt.GetEventObject() > dc = wx.BufferedPaintDC(square) > dc.Pen = wx.Pen('blakc', 2) > dc.Brush = wx.Brush('light blue') > dc.DrawRectangle(0, 0, *square.GetSize()) > > app = wx.PySimpleApp() > My_frame().Show() > app.MainLoop() > > -- > > Press the button and the panel moves to the right and then back to the > left. > While PyScripter is running the panel moves at a certain speed. You > can run the application from the Windows explorer with the same speed. > You don't need to run it from PyScripter. > When PyScripter is closed, the application runs much less quickly. > I experienced this on two PC-s. > Maybe this behavior is not even related to wxPython but to the sleep > command. I don't know... > > Thanks > iu2 You probably want to use wx.Timer rather than using time.sleep. You could use wx.Sleep() too. I don't really understand why you're doing what you're doing though. Did you re-post to the wxPython group? Mike -- http://mail.python.org/mailman/listinfo/python-list
Re: wxPython fast and slow
> def move_panel(self, evt): > def gen(): > for x in range(200): > yield x > for x in range(200, 0, -1): > yield x > for x in gen(): > self.square.SetPosition((x, 30)) > time.sleep(0.005) > I can't help with the performance problem, but you don't really need a generator for your x-values. This works: def move_panel(self, evt): for i in xrange(400): x = 200-abs(i-200) self.square.SetPosition((x, 30)) time.sleep(0.005) The generator *does* make for clearer code, though! -John -- http://mail.python.org/mailman/listinfo/python-list
Re: wxPython fast and slow
On Mar 8, 1:52 am, iu2 wrote: > On Mar 6, 6:52 pm, Mike Driscoll wrote: > > > ... > > Can you post a sample application so we can try to figure out what's > > wrong? You might also cross-post this to thewxPythonmailing list. > > They might know. > > > Mike- Hide quoted text - > > > - Show quoted text - > > Hi, thanks for your reply > > Here is a sample application: > > -- > > import wx > import time > > class My_frame(wx.Frame): > def __init__(self): > wx.Frame.__init__(self, None, -1, 'Moving panel') > self.surface = p = wx.Panel(self, size=(300, 130)) > self.square = wx.Panel(p, -1, size=(100, 100), pos=(0, 30)) > self.square.Bind(wx.EVT_PAINT, self.on_paint_square) > > btn_move = wx.Button(p, -1, 'Move panel', pos=(0, 0)) > self.Bind(wx.EVT_BUTTON, self.move_panel, btn_move) > > self.Fit() > > def move_panel(self, evt): > def gen(): > for x in range(200): > yield x > for x in range(200, 0, -1): > yield x > for x in gen(): > self.square.SetPosition((x, 30)) > time.sleep(0.005) > > def on_paint_square(self, evt): > square = evt.GetEventObject() > dc = wx.BufferedPaintDC(square) > dc.Pen = wx.Pen('blakc', 2) > dc.Brush = wx.Brush('light blue') > dc.DrawRectangle(0, 0, *square.GetSize()) > > app = wx.PySimpleApp() > My_frame().Show() > app.MainLoop() > > -- > > Press the button and the panel moves to the right and then back to the > left. > While PyScripter is running the panel moves at a certain speed. You > can run the application from the Windows explorer with the same speed. > You don't need to run it from PyScripter. > When PyScripter is closed, the application runs much less quickly. > I experienced this on two PC-s. > Maybe this behavior is not even related to wxPython but to the sleep > command. I don't know... It's not a good idea to call time.sleep inside a loop inside an event handler, which is what you are doing here. wx has a mechanism to call some sort of callback at timed intervals. (I don't know what it is but I know it has one.) Instead of animating the box move inside the button callback, have it request that a callback be called after x seconds pass, and draw a single frame inside that callback. Then invoke it again until you're done drawing. Here's a rough idea of what that might look like: class My_frame(wx.Frame): # ... among other things ... def move_panel(self,evt): self.square_pos = 0 wx.set_timed_callback_of_some_sort( self.draw_frame,0.005) def draw_frame(self): self.square.SetPosition((self.square_pos, 30)) self.square_pos += 1 if self.square_pos < 200: wx.set_timed_callback_of_some_sort( self.draw_frame,0.005) As for why it works fine in PyScripter but not when started from Explorer, well, let's just say that when you abuse callbacks like you did, you shouldn't expect reasonable behavior. Carl Banks -- http://mail.python.org/mailman/listinfo/python-list
Re: wxPython fast and slow
On Mar 6, 6:52 pm, Mike Driscoll wrote: > ... > Can you post a sample application so we can try to figure out what's > wrong? You might also cross-post this to thewxPythonmailing list. > They might know. > > Mike- Hide quoted text - > > - Show quoted text - Hi, thanks for your reply Here is a sample application: -- import wx import time class My_frame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, -1, 'Moving panel') self.surface = p = wx.Panel(self, size=(300, 130)) self.square = wx.Panel(p, -1, size=(100, 100), pos=(0, 30)) self.square.Bind(wx.EVT_PAINT, self.on_paint_square) btn_move = wx.Button(p, -1, 'Move panel', pos=(0, 0)) self.Bind(wx.EVT_BUTTON, self.move_panel, btn_move) self.Fit() def move_panel(self, evt): def gen(): for x in range(200): yield x for x in range(200, 0, -1): yield x for x in gen(): self.square.SetPosition((x, 30)) time.sleep(0.005) def on_paint_square(self, evt): square = evt.GetEventObject() dc = wx.BufferedPaintDC(square) dc.Pen = wx.Pen('blakc', 2) dc.Brush = wx.Brush('light blue') dc.DrawRectangle(0, 0, *square.GetSize()) app = wx.PySimpleApp() My_frame().Show() app.MainLoop() -- Press the button and the panel moves to the right and then back to the left. While PyScripter is running the panel moves at a certain speed. You can run the application from the Windows explorer with the same speed. You don't need to run it from PyScripter. When PyScripter is closed, the application runs much less quickly. I experienced this on two PC-s. Maybe this behavior is not even related to wxPython but to the sleep command. I don't know... Thanks iu2 -- http://mail.python.org/mailman/listinfo/python-list
Re: wxPython fast and slow
iu2 wrote: Do you have any idea of what is going wrong? I think this might be related to the OS's process prioritization, focused Windows would get more priority than background window. -- http://mail.python.org/mailman/listinfo/python-list
Re: wxPython fast and slow
On Mar 6, 8:41 am, iu2 wrote: > Hi guys, > > Can you please help me with this: > I wrote a little game in wxPython where I move small panels (showing > bitmaps (100 x 100)) on the screen. > > This is similar to the code I wrote: > > for i in xrange(1, steps + 1): > my_panel.SetPosition(...) > time.sleep(0.1 / steps) > > I use PyScripter (Windows) for writing the application. While > PyScripter is active, the panels move quickly. But when I exit > PyScripter and execute the script from the explorer or the command > line, the panels move very slowly. > > Do you have any idea of what is going wrong? > Thank you very much > > iu2 Can you post a sample application so we can try to figure out what's wrong? You might also cross-post this to the wxPython mailing list. They might know. Mike -- http://mail.python.org/mailman/listinfo/python-list
Re: wxPython fast and slow
That's weird. It might have to do with the main loop. I am not familiar with pyscripter, but it might supply a wx mainloop. However, if that is the case, I would expect the app to run slower in pyscripter, not when run without it... So can you use wx interactively from pyscripter? In other words, can you use the command line when wx windows are active? Cheers, Almar 2009/3/6 iu2 > Hi guys, > > Can you please help me with this: > I wrote a little game in wxPython where I move small panels (showing > bitmaps (100 x 100)) on the screen. > > This is similar to the code I wrote: > > for i in xrange(1, steps + 1): >my_panel.SetPosition(...) >time.sleep(0.1 / steps) > > I use PyScripter (Windows) for writing the application. While > PyScripter is active, the panels move quickly. But when I exit > PyScripter and execute the script from the explorer or the command > line, the panels move very slowly. > > Do you have any idea of what is going wrong? > Thank you very much > > iu2 > > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list
wxPython fast and slow
Hi guys, Can you please help me with this: I wrote a little game in wxPython where I move small panels (showing bitmaps (100 x 100)) on the screen. This is similar to the code I wrote: for i in xrange(1, steps + 1): my_panel.SetPosition(...) time.sleep(0.1 / steps) I use PyScripter (Windows) for writing the application. While PyScripter is active, the panels move quickly. But when I exit PyScripter and execute the script from the explorer or the command line, the panels move very slowly. Do you have any idea of what is going wrong? Thank you very much iu2 -- http://mail.python.org/mailman/listinfo/python-list