mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-06 20:10:08 +01:00
Add wx.Timer and wx.CallLater
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@69193 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -82,6 +82,7 @@ INCLUDES = [ 'defs',
|
||||
'apptrait',
|
||||
'app',
|
||||
|
||||
'timer',
|
||||
'window',
|
||||
'validate',
|
||||
'panel',
|
||||
|
||||
65
etg/timer.py
Normal file
65
etg/timer.py
Normal file
@@ -0,0 +1,65 @@
|
||||
#---------------------------------------------------------------------------
|
||||
# Name: etg/timer.py
|
||||
# Author: Robin Dunn
|
||||
#
|
||||
# Created: 21-Sept-2011
|
||||
# Copyright: (c) 2011 by Total Control Software
|
||||
# License: wxWindows License
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
import etgtools
|
||||
import etgtools.tweaker_tools as tools
|
||||
|
||||
PACKAGE = "wx"
|
||||
MODULE = "_core"
|
||||
NAME = "timer" # Base name of the file to generate to for this script
|
||||
DOCSTRING = ""
|
||||
|
||||
# The classes and/or the basename of the Doxygen XML files to be processed by
|
||||
# this script.
|
||||
ITEMS = [ 'wxTimer',
|
||||
'wxTimerRunner',
|
||||
'wxTimerEvent',
|
||||
]
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
def run():
|
||||
# Parse the XML file(s) building a collection of Extractor objects
|
||||
module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
|
||||
etgtools.parseDoxyXML(module, ITEMS)
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
# Tweak the parsed meta objects in the module object as needed for
|
||||
# customizing the generated code and docstrings.
|
||||
|
||||
c = module.find('wxTimer')
|
||||
assert isinstance(c, etgtools.ClassDef)
|
||||
|
||||
c = module.find('wxTimerRunner')
|
||||
c.addPrivateCopyCtor()
|
||||
|
||||
module.addPyCode('EVT_TIMER = wx.PyEventBinder( wxEVT_TIMER )')
|
||||
|
||||
module.addPyCode("""\
|
||||
class PyTimer(Timer):
|
||||
'''This timer class is passed the callable object to be called when the timer expires.'''
|
||||
def __init__(self, notify):
|
||||
Timer.__init__(self)
|
||||
self.notify = notify
|
||||
|
||||
def Notify(self):
|
||||
if self.notify:
|
||||
self.notify()
|
||||
""")
|
||||
|
||||
#-----------------------------------------------------------------
|
||||
tools.doCommonTweaks(module)
|
||||
tools.addGetterSetterProps(module)
|
||||
tools.runGenerators(module)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
||||
167
src/core_ex.py
167
src/core_ex.py
@@ -49,14 +49,13 @@ def deprecated(item, msg=''):
|
||||
"""
|
||||
import warnings
|
||||
if isinstance(item, type):
|
||||
# It's a class. Make a subclass that raises a warning.
|
||||
# It is a class. Make a subclass that raises a warning.
|
||||
class DeprecatedClassProxy(item):
|
||||
def __init__(*args, **kw):
|
||||
warnings.warn("Using deprecated class. %s" % msg,
|
||||
wxPyDeprecationWarning, stacklevel=2)
|
||||
item.__init__(*args, **kw)
|
||||
DeprecatedClassProxy.__name__ = item.__name__
|
||||
DeprecatedClassProxy.__doc__ = item.__doc__
|
||||
return DeprecatedClassProxy
|
||||
|
||||
elif callable(item):
|
||||
@@ -191,103 +190,103 @@ def CallAfter(callableObj, *args, **kw):
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
## class CallLater:
|
||||
## """
|
||||
## A convenience class for `wx.Timer`, that calls the given callable
|
||||
## object once after the given amount of milliseconds, passing any
|
||||
## positional or keyword args. The return value of the callable is
|
||||
## availbale after it has been run with the `GetResult` method.
|
||||
class CallLater(object):
|
||||
"""
|
||||
A convenience class for `wx.Timer`, that calls the given callable
|
||||
object once after the given amount of milliseconds, passing any
|
||||
positional or keyword args. The return value of the callable is
|
||||
availbale after it has been run with the `GetResult` method.
|
||||
|
||||
## If you don't need to get the return value or restart the timer
|
||||
## then there is no need to hold a reference to this object. It will
|
||||
## hold a reference to itself while the timer is running (the timer
|
||||
## has a reference to self.Notify) but the cycle will be broken when
|
||||
## the timer completes, automatically cleaning up the wx.CallLater
|
||||
## object.
|
||||
If you don't need to get the return value or restart the timer
|
||||
then there is no need to hold a reference to this object. It will
|
||||
hold a reference to itself while the timer is running (the timer
|
||||
has a reference to self.Notify) but the cycle will be broken when
|
||||
the timer completes, automatically cleaning up the wx.CallLater
|
||||
object.
|
||||
|
||||
## :see: `wx.CallAfter`
|
||||
## """
|
||||
## def __init__(self, millis, callableObj, *args, **kwargs):
|
||||
## assert callable(callableObj), "callableObj is not callable"
|
||||
## self.millis = millis
|
||||
## self.callable = callableObj
|
||||
## self.SetArgs(*args, **kwargs)
|
||||
## self.runCount = 0
|
||||
## self.running = False
|
||||
## self.hasRun = False
|
||||
## self.result = None
|
||||
## self.timer = None
|
||||
## self.Start()
|
||||
:see: `wx.CallAfter`
|
||||
"""
|
||||
def __init__(self, millis, callableObj, *args, **kwargs):
|
||||
assert callable(callableObj), "callableObj is not callable"
|
||||
self.millis = millis
|
||||
self.callable = callableObj
|
||||
self.SetArgs(*args, **kwargs)
|
||||
self.runCount = 0
|
||||
self.running = False
|
||||
self.hasRun = False
|
||||
self.result = None
|
||||
self.timer = None
|
||||
self.Start()
|
||||
|
||||
## def __del__(self):
|
||||
## self.Stop()
|
||||
def __del__(self):
|
||||
self.Stop()
|
||||
|
||||
|
||||
## def Start(self, millis=None, *args, **kwargs):
|
||||
## """
|
||||
## (Re)start the timer
|
||||
## """
|
||||
## self.hasRun = False
|
||||
## if millis is not None:
|
||||
## self.millis = millis
|
||||
## if args or kwargs:
|
||||
## self.SetArgs(*args, **kwargs)
|
||||
## self.Stop()
|
||||
## self.timer = wx.PyTimer(self.Notify)
|
||||
## self.timer.Start(self.millis, wx.TIMER_ONE_SHOT)
|
||||
## self.running = True
|
||||
## Restart = Start
|
||||
def Start(self, millis=None, *args, **kwargs):
|
||||
"""
|
||||
(Re)start the timer
|
||||
"""
|
||||
self.hasRun = False
|
||||
if millis is not None:
|
||||
self.millis = millis
|
||||
if args or kwargs:
|
||||
self.SetArgs(*args, **kwargs)
|
||||
self.Stop()
|
||||
self.timer = wx.PyTimer(self.Notify)
|
||||
self.timer.Start(self.millis, wx.TIMER_ONE_SHOT)
|
||||
self.running = True
|
||||
Restart = Start
|
||||
|
||||
|
||||
## def Stop(self):
|
||||
## """
|
||||
## Stop and destroy the timer.
|
||||
## """
|
||||
## if self.timer is not None:
|
||||
## self.timer.Stop()
|
||||
## self.timer = None
|
||||
def Stop(self):
|
||||
"""
|
||||
Stop and destroy the timer.
|
||||
"""
|
||||
if self.timer is not None:
|
||||
self.timer.Stop()
|
||||
self.timer = None
|
||||
|
||||
|
||||
## def GetInterval(self):
|
||||
## if self.timer is not None:
|
||||
## return self.timer.GetInterval()
|
||||
## else:
|
||||
## return 0
|
||||
def GetInterval(self):
|
||||
if self.timer is not None:
|
||||
return self.timer.GetInterval()
|
||||
else:
|
||||
return 0
|
||||
|
||||
|
||||
## def IsRunning(self):
|
||||
## return self.timer is not None and self.timer.IsRunning()
|
||||
def IsRunning(self):
|
||||
return self.timer is not None and self.timer.IsRunning()
|
||||
|
||||
|
||||
## def SetArgs(self, *args, **kwargs):
|
||||
## """
|
||||
## (Re)set the args passed to the callable object. This is
|
||||
## useful in conjunction with Restart if you want to schedule a
|
||||
## new call to the same callable object but with different
|
||||
## parameters.
|
||||
## """
|
||||
## self.args = args
|
||||
## self.kwargs = kwargs
|
||||
def SetArgs(self, *args, **kwargs):
|
||||
"""
|
||||
(Re)set the args passed to the callable object. This is
|
||||
useful in conjunction with Restart if you want to schedule a
|
||||
new call to the same callable object but with different
|
||||
parameters.
|
||||
"""
|
||||
self.args = args
|
||||
self.kwargs = kwargs
|
||||
|
||||
|
||||
## def HasRun(self):
|
||||
## return self.hasRun
|
||||
def HasRun(self):
|
||||
return self.hasRun
|
||||
|
||||
## def GetResult(self):
|
||||
## return self.result
|
||||
def GetResult(self):
|
||||
return self.result
|
||||
|
||||
## def Notify(self):
|
||||
## """
|
||||
## The timer has expired so call the callable.
|
||||
## """
|
||||
## if self.callable and getattr(self.callable, 'im_self', True):
|
||||
## self.runCount += 1
|
||||
## self.running = False
|
||||
## self.result = self.callable(*self.args, **self.kwargs)
|
||||
## self.hasRun = True
|
||||
## if not self.running:
|
||||
## # if it wasn't restarted, then cleanup
|
||||
## wx.CallAfter(self.Stop)
|
||||
def Notify(self):
|
||||
"""
|
||||
The timer has expired so call the callable.
|
||||
"""
|
||||
if self.callable and getattr(self.callable, 'im_self', True):
|
||||
self.runCount += 1
|
||||
self.running = False
|
||||
self.result = self.callable(*self.args, **self.kwargs)
|
||||
self.hasRun = True
|
||||
if not self.running:
|
||||
# if it wasn't restarted, then cleanup
|
||||
wx.CallAfter(self.Stop)
|
||||
|
||||
## Interval = property(GetInterval)
|
||||
## Result = property(GetResult)
|
||||
Interval = property(GetInterval)
|
||||
Result = property(GetResult)
|
||||
|
||||
93
unittests/test_timer.py
Normal file
93
unittests/test_timer.py
Normal file
@@ -0,0 +1,93 @@
|
||||
import imp_unittest, unittest
|
||||
import wtc
|
||||
import wx
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
class timer_Tests(wtc.WidgetTestCase):
|
||||
|
||||
def waitFor(self, milliseconds):
|
||||
intervals = milliseconds/100
|
||||
while intervals > 0:
|
||||
wx.MilliSleep(100)
|
||||
self.myYield()
|
||||
if hasattr(self, 'flag') and self.flag:
|
||||
break
|
||||
intervals -= 1
|
||||
|
||||
|
||||
def onTimerEvt(self, *evt):
|
||||
self.flag = True
|
||||
|
||||
|
||||
def test_timerOwner1(self):
|
||||
t = wx.Timer(self.frame)
|
||||
self.flag = False
|
||||
self.frame.Bind(wx.EVT_TIMER, self.onTimerEvt, t)
|
||||
t.Start(250, wx.TIMER_ONE_SHOT)
|
||||
self.waitFor(500)
|
||||
self.assertTrue(self.flag)
|
||||
|
||||
|
||||
def test_timerOwner2(self):
|
||||
t = wx.Timer(self.frame)
|
||||
self.flag = False
|
||||
self.frame.Bind(wx.EVT_TIMER, self.onTimerEvt, t)
|
||||
t.Start(1000, wx.TIMER_ONE_SHOT)
|
||||
# timer will not have expired yet by this time, so flag shouldn't be set
|
||||
self.waitFor(500)
|
||||
self.assertFalse(self.flag)
|
||||
|
||||
|
||||
def test_timerPyTimer(self):
|
||||
t = wx.PyTimer(self.onTimerEvt)
|
||||
self.flag = False
|
||||
t.Start(250, wx.TIMER_ONE_SHOT)
|
||||
self.waitFor(500)
|
||||
self.assertTrue(self.flag)
|
||||
|
||||
|
||||
def test_timerDerivedClass(self):
|
||||
class MyTimer(wx.Timer):
|
||||
def __init__(self):
|
||||
wx.Timer.__init__(self)
|
||||
self.flag = False
|
||||
def Notify(self):
|
||||
self.flag = True
|
||||
|
||||
t = MyTimer()
|
||||
t.Start(250, wx.TIMER_ONE_SHOT)
|
||||
self.waitFor(500)
|
||||
self.assertTrue(t.flag)
|
||||
|
||||
|
||||
def onCallLater(self):
|
||||
self.flag = True
|
||||
return 1234
|
||||
|
||||
def test_timerCallLater1(self):
|
||||
# simple CallLater usage
|
||||
wx.CallLater(250, self.onCallLater)
|
||||
self.waitFor(500)
|
||||
self.assertTrue(self.flag)
|
||||
|
||||
|
||||
def test_timerCallLater2(self):
|
||||
# test getting the result and restarting the CallLater
|
||||
cl = wx.CallLater(250, self.onCallLater)
|
||||
self.assertTrue(cl.IsRunning())
|
||||
self.waitFor(500)
|
||||
self.assertTrue(self.flag)
|
||||
self.assertTrue(cl.GetResult() == 1234)
|
||||
self.flag = False
|
||||
cl.Restart()
|
||||
self.waitFor(500)
|
||||
self.assertTrue(self.flag)
|
||||
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user