]> git.saurik.com Git - wxWidgets.git/blobdiff - wxPython/demo/Timer.py
fixes for unicode build, return values from event handlers (via
[wxWidgets.git] / wxPython / demo / Timer.py
index 86892c7f88203492a8ffbc9ff9467a10d7b49d30..af5e77e43d9e3f5f5f5b6317ddc0dcd4ca0979ae 100644 (file)
-# 
-# 1/11/2004 - Jeff Grimmett (grimmtooth@softhome.net)
-#
-# o It appears that wx.Timer has an issue where if you use
-#
-#       self.timer = wx.Timer(self, -1)
-#
-#   to create it, then
-#
-#       self.timer.GetId()
-#
-#   doesn't seem to return anything meaningful. In the demo, doing this
-#   results in only one of the two handlers being called for both timers.
-#   This means that
-#
-#       self.Bind(wx.EVT_TIMER, self.onTimer, self.timer)
-#
-#   doesn't work right. However, using
-#
-#       self.timer = wx.Timer(self, wx.NewId())
-#
-#   makes it work OK. I believe this is a bug, but wiser heads than mine
-#   should determine this.
-#
-
 import  time
 import  wx
 import  time
 import  wx
+import  wx.lib.scrolledpanel as sp
+
+#----------------------------------------------------------------------
+
+
+header = """\
+This demo shows the various ways that wx.Timers can be used in your code.  Just
+select one of the buttons in the left column to start a timer in the indicated way,
+and watch the log window below for messages printed when the timer event or callback
+happens.  Clicking the corresponding button on the right will stop that timer.  Since
+timers are not owned by any other wx object you should hold on to a reference to the
+timer until you are completely finished with it. """
+
+doc1 = """\
+Binding an event handler to the wx.EVT_TIMER event is the
+prefered way to use the wx.Timer class directly.  It makes
+handling timer events work just like normal window events.  You
+just need to specify the window that is to receive the event in
+the wx.Timer constructor.  If that window needs to be able to
+receive events from more than one timer then you can optionally
+specify an ID for the timer and the event binding.
+"""
+
+
+doc2 = """\
+wx.FutureCall is a convenience class for wx.Timer.  You just
+specify the timeout in milliseconds and a callable object, along
+with any ard or keyword arg you woudl like to be passed to your
+callable, and wx.FutureCall takes care of the rest.  If you don't
+need to get the return value of the callable or to restart the
+timer then there is no need to hold a reference to this object.
+"""
+
+
+doc3 = """\
+If you derive a class from wx.Timer and give it a Notify method
+then it will be called when the timer expires.
+"""
 
 
-#---------------------------------------------------------------------------
 
 
-## For your convenience; an example of creating your own timer class.
-##
-## class TestTimer(wx.Timer):
-##     def __init__(self, log = None):
-##         wx.Timer.__init__(self)
-##         self.log = log
-##     def Notify(self):
-##         wx.Bell()
-##         if self.log:
-##             self.log.WriteText('beep!\n')
+doc4 = """\
+wx.PyTimer is the old way (a kludge that goes back all the way to
+the first version of wxPython) to bind a timer directly to a
+callable.  You should migrate any code that uses this method to
+use EVT_TIMER instead as this may be deprecated in the future.
+"""
 
 
-#---------------------------------------------------------------------------
 
 
-class TestTimerWin(wx.Panel):
+class TestPanel(sp.ScrolledPanel):
     def __init__(self, parent, log):
     def __init__(self, parent, log):
-        wx.Panel.__init__(self, parent, -1)
         self.log = log
         self.log = log
+        sp.ScrolledPanel.__init__(self, parent, -1)
+
+        outsideSizer = wx.BoxSizer(wx.VERTICAL)
+
+        text = wx.StaticText(self, -1, "wx.Timer", style=wx.ALIGN_CENTRE)
+        text.SetFont(wx.Font(24, wx.SWISS, wx.NORMAL, wx.BOLD, False))
+        text.SetSize(text.GetBestSize())
+        text.SetForegroundColour(wx.BLUE)
+        outsideSizer.Add(text, 0, wx.EXPAND|wx.ALL, 5)
+        outsideSizer.Add(wx.StaticText(self, -1, header), 0, wx.ALIGN_CENTER|wx.ALL, 5)
+        outsideSizer.Add(wx.StaticLine(self, -1), 0, wx.EXPAND)
+        outsideSizer.Add((20,20))
+
+
+        t1b1 = wx.Button(self, -1, "EVT_TIMER")
+        t1b2 = wx.Button(self, -1, "stop timer")
+        t1st = wx.StaticText(self, -1, doc1)
+        t1b2.Disable()
+        self.Bind(wx.EVT_BUTTON, self.OnTest1Start, t1b1)
+        self.Bind(wx.EVT_BUTTON, self.OnTest1Stop,  t1b2)
+
+        # Bind all EVT_TIMER events to self.OnTest1Timer
+        self.Bind(wx.EVT_TIMER, self.OnTest1Timer)
+
+        
+        t2b1 = wx.Button(self, -1, "wx.FutureCall")
+        t2b2 = wx.Button(self, -1, "stop timer")
+        t2st = wx.StaticText(self, -1, doc2)
+        t2b2.Disable()
+        self.Bind(wx.EVT_BUTTON, self.OnTest2Start, t2b1)
+        self.Bind(wx.EVT_BUTTON, self.OnTest2Stop,  t2b2)
+
+        t3b1 = wx.Button(self, -1, "self.Notify")
+        t3b2 = wx.Button(self, -1, "stop timer")
+        t3st = wx.StaticText(self, -1, doc3)
+        t3b2.Disable()
+        self.Bind(wx.EVT_BUTTON, self.OnTest3Start, t3b1)
+        self.Bind(wx.EVT_BUTTON, self.OnTest3Stop,  t3b2)
+
+        t4b1 = wx.Button(self, -1, "wx.PyTimer")
+        t4b2 = wx.Button(self, -1, "stop timer")
+        t4st = wx.StaticText(self, -1, doc4)
+        t4b2.Disable()
+        self.Bind(wx.EVT_BUTTON, self.OnTest4Start, t4b1)
+        self.Bind(wx.EVT_BUTTON, self.OnTest4Stop,  t4b2)
+
+
+        self.t1b2 = t1b2
+        self.t2b2 = t2b2
+        self.t3b2 = t3b2
+        self.t4b2 = t4b2
+
+        fgs = wx.FlexGridSizer(cols=3, hgap=10, vgap=10)
+        fgs.Add(t1b1)
+        fgs.Add(t1b2)
+        fgs.Add(t1st)
 
 
-        wx.StaticText(self, -1, "This is a timer example", (15, 30))
-        startBtn = wx.Button(self, -1, ' Start ', (15, 75), wx.DefaultSize)
-        stopBtn = wx.Button(self, -1, ' Stop ', (115, 75), wx.DefaultSize)
+        fgs.Add(t2b1)
+        fgs.Add(t2b2)
+        fgs.Add(t2st)
 
 
-        self.timer = wx.Timer(self, wx.NewId())
-        self.timer2 = wx.Timer(self, wx.NewId())  
+        fgs.Add(t3b1)
+        fgs.Add(t3b2)
+        fgs.Add(t3st)
 
 
-        self.Bind(wx.EVT_BUTTON, self.OnStart, startBtn)
-        self.Bind(wx.EVT_BUTTON, self.OnStop, stopBtn)
-        self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)
-        self.Bind(wx.EVT_TIMER, self.OnTimer2, self.timer2)
+        fgs.Add(t4b1)
+        fgs.Add(t4b2)
+        fgs.Add(t4st)
+        
+        outsideSizer.Add(fgs, 0, wx.ALIGN_CENTER|wx.ALL, 10)
+        self.SetSizer(outsideSizer)
+        self.SetupScrolling()
+        
 
 
-    def OnStart(self, event):
-        self.timer.Start(1000)
-        self.timer2.Start(1500)
+    # Test 1 shows how to use a timer to generate EVT_TIMER
+    # events, by passing self to the wx.Timer constructor.  The
+    # event is bound above to the OnTest1Timer method.
+    
+    def OnTest1Start(self, evt):
+        self.t1 = wx.Timer(self)
+        self.t1.Start(1000)
+        self.log.write("EVT_TIMER timer started\n")
+        self.t1b2.Enable()
 
 
-    def OnStop(self, event):
-        self.timer.Stop()
-        self.timer2.Stop()
+    def OnTest1Stop(self, evt):
+        self.t1.Stop()
+        self.log.write("EVT_TIMER timer stoped\n")
+        del self.t1
+        self.t1b2.Disable()
 
 
-    def OnTimer(self, event):
-        wx.Bell()
-        if self.log:
-            self.log.WriteText('beep!\n')
+    def OnTest1Timer(self, evt):
+        self.log.write("got EVT_TIMER event\n")
+    
 
 
-    def OnTimer2(self, event):
-        wx.Bell()
-        if self.log:
-            self.log.WriteText('beep 2!\n')
 
 
-#---------------------------------------------------------------------------
+    # Test 2 shows how to use the wx.FutureCall class.
+    
+    def OnTest2Start(self, evt):
+        # Call OnTest2Timer one second in the future, passing some
+        # optional arbitrary args.  There is no need to hold a
+        # reference to this one, unless we want to manipulate or query
+        # it later like we do in the two methods below
+        self.t2 = wx.FutureCall(1000, self.OnTest2Timer,
+                                'a', 'b', 'c', one=1, two=2)
+        self.log.write("FutureCall scheduled\n")
+        self.t2b2.Enable()
+        
+    def OnTest2Stop(self, evt):
+        self.t2.Stop()
+        self.log.write("FutureCall stopped, last return value was: %s\n" %
+                       repr(self.t2.GetResult()))
+        del self.t2
+        self.t2b2.Disable()
+           
+    def OnTest2Timer(self, *args, **kw):
+        self.log.write("FutureCall called with args=%s, kwargs=%s\n" % (args, kw))
+
+        # Normally a FutureCall is one-shot, but we can make it
+        # recurring just by calling Restart.  We can even use a
+        # different timeout or pass differnt args this time.
+        self.t2.Restart(1500, "restarted")
+
+        # The return value of this function is saved and can be
+        # retrived later.  See OnTest2Stop above.
+        return "This is my return value"
+
+
+
+    # Test 3 shows how to use a class derived from wx.Timer.  See
+    # also the NotifyTimer class below.
+    
+    def OnTest3Start(self, evt):
+        self.t3 = NotifyTimer(self.log)
+        self.t3.Start(1000)
+        self.log.write("NotifyTimer timer started\n")
+        self.t3b2.Enable()
+
+    def OnTest3Stop(self, evt):
+        self.t3.Stop()
+        self.log.write("NotifyTimer timer stoped\n")
+        del self.t3
+        self.t3b2.Disable()
+
+
+
+    # Test 4 shows the old way (a kludge that goes back all the
+    # way to the first version of wxPython) to bind a timer
+    # directly to a callable.  You should migrate any code that
+    # uses this method to use EVT_TIMER instead as this may be
+    # deprecated in the future.
+    def OnTest4Start(self, evt):
+        self.t4 = wx.PyTimer(self.OnTest4Timer)
+        self.t4.Start(1000)
+        self.log.write("wx.PyTimer timer started\n")
+        self.t4b2.Enable()
+
+    def OnTest4Stop(self, evt):
+        self.t4.Stop()
+        self.log.write("wx.PyTimer timer stoped\n")
+        del self.t4
+        self.t4b2.Disable()
+
+    def OnTest4Timer(self):
+        self.log.write("got wx.PyTimer event\n")
+    
+
+
+#----------------------------------------------------------------------
+
+
+# When deriving from wx.Timer you must provide a Notify method
+# that will be called when the timer expires.
+class NotifyTimer(wx.Timer):
+    def __init__(self, log):
+        wx.Timer.__init__(self)
+        self.log = log
+        
+    def Notify(self):
+        log.write("got NotifyTimer event\n")
+
+
+
+#----------------------------------------------------------------------
 
 def runTest(frame, nb, log):
 
 def runTest(frame, nb, log):
-    win = TestTimerWin(nb, log)
+    win = TestPanel(nb, log)
     return win
 
     return win
 
-#---------------------------------------------------------------------------
 
 
+#----------------------------------------------------------------------
 
 
+overview = """<html><body>
+<h2><center>wx.Timer</center></h2>
 
 
-overview = """\
-The wx.Timer class allows you to execute code at specified intervals from
-within the wxPython event loop. Timers can be one-shot or repeating.
+The wx.Timer class allows you to execute code at specified intervals
+from within the wxPython event loop. Timers can be one-shot or
+repeating.  This demo shows the principle method of using a timer
+(with events) as well as the convenient wx.FutureCall class.  Also
+there are two other usage patterns shown here that have been preserved
+for backwards compatibility.
 
 
+</body></html>
 """
 
 
 
 """
 
 
 
-
 if __name__ == '__main__':
     import sys,os
     import run
 if __name__ == '__main__':
     import sys,os
     import run
-    run.main(['', os.path.basename(sys.argv[0])])
+    run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])
+
+
+
+