wxpython wx.Slider: how to fire an event only if a user pauses for some predetermined time
Question: I have a `wx.Slider` widget that is bound to an event handler. As a user moves
the slider, some process will run. However, because the process can take up to
3 seconds to run, I don't want the event to fire continuously as the user
moves the slider. Instead, I want the event to fire only if the user stops
moving the slider for some amount of time (say, 2 seconds). I tried using
`time.time()` with a `while`-loop (see code below), but it didn't work because
the event would still fire repeatedly -- it's just that the firing got
delayed. Any idea/pointer/suggestion would be greatly appreciated.

    
    
    import wx
    import time
    
    class Example(wx.Frame):
    
        def __init__(self, *args, **kw):
            super(Example, self).__init__(*args, **kw) 
            self.InitUI()
    
        def InitUI(self):   
            pnl = wx.Panel(self)
            sld = wx.Slider(pnl, value=200, minValue=150, maxValue=500, pos=(20, 20), 
                            size=(250, -1), style=wx.SL_HORIZONTAL)        
            self.counter = 0
            sld.Bind(wx.EVT_SCROLL, self.OnSliderScroll)
    
            self.txt = wx.StaticText(pnl, label='200', pos=(20, 90))               
    
            self.SetSize((290, 200))
            self.SetTitle('wx.Slider')
            self.Centre()
            self.Show(True)    
    
        def OnSliderScroll(self, e):        
            now = time.time()
            future = now + 2
            while time.time() < future:
                pass
            #substitute for the actual process.
            self.counter += 1
            print self.counter
    
    
    def main():    
        ex = wx.App()
        Example(None)
        ex.MainLoop()    
    
    if __name__ == '__main__':
        main()   
    


Answer: Delaying with `time.sleep` will block your GUI. Use `wx.CallLater` instead,
which in the sample below will trigger the delayed event until it has been
restarted again.

    
    
        def InitUi(self):
            # ...
    
            # Add a delay timer, set it up and stop it
            self.delay_slider_evt = wx.CallLater(2000, self.delayed_event)
            self.delay_slider_evt.Stop()
    
        def OnSliderScroll(self, e):
            # if delay timer does not run, start it, either restart it
            if not self.delay_slider_evt.IsRunning():
                self.delay_slider_evt.Start(2000)
            else:
                self.delay_slider_evt.Restart(2000)
    
        def delayed_event(self):
            #substitute for the actual delayed process.
            self.counter += 1
            print self.counter
    

