X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/95bfd958bda8955ac81277c78e5627c926154f39..0dabb2a2c6ae27df135da4752b00579346bb74fc:/wxPython/demo/Timer.py?ds=sidebyside diff --git a/wxPython/demo/Timer.py b/wxPython/demo/Timer.py index 86892c7f88..af5e77e43d 100644 --- a/wxPython/demo/Timer.py +++ b/wxPython/demo/Timer.py @@ -1,101 +1,267 @@ -# -# 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 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): - wx.Panel.__init__(self, parent, -1) 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): - win = TestTimerWin(nb, log) + win = TestPanel(nb, log) return win -#--------------------------------------------------------------------------- +#---------------------------------------------------------------------- +overview = """ +

wx.Timer

-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. + """ - 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:]) + + + +