hi,
I’m facing an issue when develope a mplayer front-end app use wxpython, in my application, I use a wx.Timer instance and bind a handler function with it to update the progress bar when playing a media, but I found the events occured are stored as a queue which means my other event handlers are blocked(actually delayed) since lots of timer event occured before the event which I’d like to be handled imediately. for instance, when I click on the pause button, its handler OnPause() which disable the pause button itself and pause the play should be executed immediately, but in practice, the pause behavor was always delayed to wait for several timer events to be processed.
I’m pretty new to wxpython, actually I’ve zero experience on gui programming, so just feel free to point out I’m walking on a stupid way, guide me to the right direction is much appreciated. here is some pieces of my fucking codes.
In MainWindow.py
…
self.Bind(wx.EVT_TIMER, self.OnTimerEvent, self.timer)
Publisher().subscribe(self.UpdateProgressBar, ‘Controler.ProgressBar.Update’)
…
def OnTimerEvent(self, event):
if MplayerState.state == MplayerState.PLAYING:
t = Thread(target=self.ctl.UpdateProgressBar)
t.setDaemon(True)
t.start() #time.sleep(0)
else:
self.StopTimer()
debug(‘Timer Event: current player state - %s’ % MplayerState.states[MplayerState.state])
event.Skip()
…
def UpdateProgressBar(self, msg):
try:
self.lock.acquire()
if MplayerState.state == MplayerState.PLAYING:
percent = msg.data
debug(‘MainWindow: UpdateProgressBar - percent = %s’ % percent)
self.progress_bar.SetValue(percent)
self.lock.release()
if percent == 1000:
self.StopTimer()
return
else:
self.lock.release()
hi,
I'm facing an issue when develope a mplayer front-end app use wxpython, in my application, I use a wx.Timer instance and bind a handler function with it to update the progress bar when playing a media, but I found the events occured are stored as a queue which means my other event handlers are blocked(actually delayed) since lots of timer event occured *before* the event which I'd like to be handled imediately. for instance, when I click on the pause button, its handler OnPause() which disable the pause button itself and pause the play should be executed immediately, but in practice, the pause behavor was always *delayed* to wait for several timer events to be processed.
IIRC, timer events are relatively low priority so if there are other events pending then the timer events may not be sent until they have been processed. This may be part of what you are seeing. Another part may be that if the ui thread gets blocked waiting for some function to return then there will be no events delivered at all until the (relatively) long running task completes.
It's not real clear from your code snippets but it looks like you may be breaking the thread rule. In a nutshell you should not invoke any function or method that accesses or manipulates a UI object from a thread that is not the UI thread. See LongRunningTasks - wxPyWiki and Non-Blocking Gui - wxPyWiki
···
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!
IIRC, timer events are relatively low priority so if there are other events pending then the timer events may not be sent until they have been processed. This may be part of what you are seeing. Another part may be that if the ui thread gets blocked waiting for some function to return then there will be no events delivered at all until the (relatively) long running task completes.
It’s not real clear from your code snippets but it looks like you may be breaking the thread rule. In a nutshell you should not invoke any function or method that accesses or manipulates a UI object from a thread that is not the UI thread. See http://wiki.wxpython.org/LongRunningTasks and http://wiki.wxpython.org/Non-Blocking_Gui
Robin,
the issue I’m suffering is the timer event seems has higher priority that other event such as EVT_BUTTON, and my event handler to handle pause button clicked have to wait for several timer events processed and caused a unexpected delayed response to user, and I’m not breaking the thread rule actually, I do all ui refresh operations in gui main thread, below is the event handle procedure for a timer event.
···
On Thu, Nov 20, 2008 at 6:24 AM, Robin Dunn robin@alldunn.com wrote:
it seems like wxpython are busy working on the events generated by Publisher(), it maybe has a much more higher priority compared to timer event or button clicked event?
On Thu, Nov 20, 2008 at 6:24 AM, Robin Dunn robin@alldunn.com wrote:
IIRC, timer events are relatively low priority so if there are other events pending then the timer events may not be sent until they have been processed. This may be part of what you are seeing. Another part may be that if the ui thread gets blocked waiting for some function to return then there will be no events delivered at all until the (relatively) long running task completes.
It’s not real clear from your code snippets but it looks like you may be breaking the thread rule. In a nutshell you should not invoke any function or method that accesses or manipulates a UI object from a thread that is not the UI thread. See http://wiki.wxpython.org/LongRunningTasks and http://wiki.wxpython.org/Non-Blocking_Gui
Robin,
the issue I’m suffering is the timer event seems has higher priority that other event such as EVT_BUTTON, and my event handler to handle pause button clicked have to wait for several timer events processed and caused a unexpected delayed response to user, and I’m not breaking the thread rule actually, I do all ui refresh operations in gui main thread, below is the event handle procedure for a timer event.
IIRC, timer events are relatively low priority so if there are other
events pending then the timer events may not be sent until they have
been processed. This may be part of what you are seeing. Another
part may be that if the ui thread gets blocked waiting for some
function to return then there will be no events delivered at all
until the (relatively) long running task completes.
It's not real clear from your code snippets but it looks like you
may be breaking the thread rule. In a nutshell you should not
invoke any function or method that accesses or manipulates a UI
object from a thread that is not the UI thread. See LongRunningTasks - wxPyWiki and Non-Blocking Gui - wxPyWiki
-- Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!
Robin, the issue I'm suffering is the timer event seems has higher priority that other event such as EVT_BUTTON, and my event handler to handle pause button clicked have to wait for several timer events processed and caused a unexpected delayed response to user, and I'm not breaking the thread rule actually, I do all ui refresh operations in gui main thread, below is the event handle procedure for a timer event.
Sending a publisher message does not do anything about the thread context that the subscriber is run in. It will use the same thread as the sendMessage() call, so unless I'm missing something, your "self.progress_bar.SetValue(percent)" is likely still happening in the worker thread.
it seems like wxpython are busy working on the events generated by Publisher(), it maybe has a much more higher priority compared to timer event or button clicked event?
Publisher doesn't use events and doesn't do any queuing of messages. When you call sendMessage it will call the subscribed functions immediately, before sendMessage returns.
···
On Thu, Nov 20, 2008 at 6:24 AM, Robin Dunn <robin@alldunn.com > <mailto:robin@alldunn.com>> wrote:
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!
Sending a publisher message does not do anything about the thread context that the subscriber is run in. It will use the same thread as the sendMessage() call, so unless I’m missing something, your “self.progress_bar.SetValue(percent)” is likely still happening in the worker thread.
it seems like wxpython are busy working on the events generated by Publisher(), it maybe has a much more higher priority compared to timer event or button clicked event?
Publisher doesn’t use events and doesn’t do any queuing of messages. When you call sendMessage it will call the subscribed functions immediately, before sendMessage returns.
I see, I got a stupid understanding of how Publisher() works, so send a custom event instead of a Publisher message will do the trick? Really appreciate your great help, thanks a lot.
Sending a publisher message does not do anything about the thread
context that the subscriber is run in. It will use the same
thread as the sendMessage() call, so unless I'm missing something,
your "self.progress_bar.SetValue(percent)" is likely still
happening in the worker thread.
it seems like wxpython are busy working on the events
generated by Publisher(), it maybe has a much more higher
priority compared to timer event or button clicked event?
Publisher doesn't use events and doesn't do any queuing of
messages. When you call sendMessage it will call the subscribed
functions immediately, before sendMessage returns.
-- Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!
I see, I got a *stupid* understanding of how Publisher() works, so send a custom event instead of a Publisher message will do the trick? Really appreciate your great help, thanks a lot.
You can use wx.CallAfter() to call the publisher module's sendMessage method because CallAfter is "thread-safe". There are other methods to do this sort of thing. Just browse the archives a bit. I recall one thread within the last month or two even.
You can use wx.CallAfter() to call the publisher module’s sendMessage method because CallAfter is “thread-safe”. There are other methods to do this sort of thing. Just browse the archives a bit. I recall one thread within the last month or two even.
I see, I got a *stupid* understanding of how Publisher() works, so send a custom event instead of a Publisher message will do the trick?
wx.CallAfter uses an event to do its work, so it is an easy way to safely cause something to be executed in the context of the UI thread. You can also combine it with the use of the publisher if desired. (IOW, have the subscribed function call the real function using wx.CallAfter.)
···
--
Robin Dunn
Software Craftsman http://wxPython.org Java give you jitters? Relax with wxPython!