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',
|
'apptrait',
|
||||||
'app',
|
'app',
|
||||||
|
|
||||||
|
'timer',
|
||||||
'window',
|
'window',
|
||||||
'validate',
|
'validate',
|
||||||
'panel',
|
'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()
|
||||||
|
|
||||||
171
src/core_ex.py
171
src/core_ex.py
@@ -49,14 +49,13 @@ def deprecated(item, msg=''):
|
|||||||
"""
|
"""
|
||||||
import warnings
|
import warnings
|
||||||
if isinstance(item, type):
|
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):
|
class DeprecatedClassProxy(item):
|
||||||
def __init__(*args, **kw):
|
def __init__(*args, **kw):
|
||||||
warnings.warn("Using deprecated class. %s" % msg,
|
warnings.warn("Using deprecated class. %s" % msg,
|
||||||
wxPyDeprecationWarning, stacklevel=2)
|
wxPyDeprecationWarning, stacklevel=2)
|
||||||
item.__init__(*args, **kw)
|
item.__init__(*args, **kw)
|
||||||
DeprecatedClassProxy.__name__ = item.__name__
|
DeprecatedClassProxy.__name__ = item.__name__
|
||||||
DeprecatedClassProxy.__doc__ = item.__doc__
|
|
||||||
return DeprecatedClassProxy
|
return DeprecatedClassProxy
|
||||||
|
|
||||||
elif callable(item):
|
elif callable(item):
|
||||||
@@ -191,103 +190,103 @@ def CallAfter(callableObj, *args, **kw):
|
|||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
## class CallLater:
|
class CallLater(object):
|
||||||
## """
|
"""
|
||||||
## A convenience class for `wx.Timer`, that calls the given callable
|
A convenience class for `wx.Timer`, that calls the given callable
|
||||||
## object once after the given amount of milliseconds, passing any
|
object once after the given amount of milliseconds, passing any
|
||||||
## positional or keyword args. The return value of the callable is
|
positional or keyword args. The return value of the callable is
|
||||||
## availbale after it has been run with the `GetResult` method.
|
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.
|
||||||
|
|
||||||
|
: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()
|
||||||
|
|
||||||
## If you don't need to get the return value or restart the timer
|
def __del__(self):
|
||||||
## then there is no need to hold a reference to this object. It will
|
self.Stop()
|
||||||
## 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()
|
|
||||||
|
|
||||||
## def __del__(self):
|
|
||||||
## self.Stop()
|
|
||||||
|
|
||||||
|
|
||||||
## def Start(self, millis=None, *args, **kwargs):
|
def Start(self, millis=None, *args, **kwargs):
|
||||||
## """
|
"""
|
||||||
## (Re)start the timer
|
(Re)start the timer
|
||||||
## """
|
"""
|
||||||
## self.hasRun = False
|
self.hasRun = False
|
||||||
## if millis is not None:
|
if millis is not None:
|
||||||
## self.millis = millis
|
self.millis = millis
|
||||||
## if args or kwargs:
|
if args or kwargs:
|
||||||
## self.SetArgs(*args, **kwargs)
|
self.SetArgs(*args, **kwargs)
|
||||||
## self.Stop()
|
self.Stop()
|
||||||
## self.timer = wx.PyTimer(self.Notify)
|
self.timer = wx.PyTimer(self.Notify)
|
||||||
## self.timer.Start(self.millis, wx.TIMER_ONE_SHOT)
|
self.timer.Start(self.millis, wx.TIMER_ONE_SHOT)
|
||||||
## self.running = True
|
self.running = True
|
||||||
## Restart = Start
|
Restart = Start
|
||||||
|
|
||||||
|
|
||||||
## def Stop(self):
|
def Stop(self):
|
||||||
## """
|
"""
|
||||||
## Stop and destroy the timer.
|
Stop and destroy the timer.
|
||||||
## """
|
"""
|
||||||
## if self.timer is not None:
|
if self.timer is not None:
|
||||||
## self.timer.Stop()
|
self.timer.Stop()
|
||||||
## self.timer = None
|
self.timer = None
|
||||||
|
|
||||||
|
|
||||||
## def GetInterval(self):
|
def GetInterval(self):
|
||||||
## if self.timer is not None:
|
if self.timer is not None:
|
||||||
## return self.timer.GetInterval()
|
return self.timer.GetInterval()
|
||||||
## else:
|
else:
|
||||||
## return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
## def IsRunning(self):
|
def IsRunning(self):
|
||||||
## return self.timer is not None and self.timer.IsRunning()
|
return self.timer is not None and self.timer.IsRunning()
|
||||||
|
|
||||||
|
|
||||||
## def SetArgs(self, *args, **kwargs):
|
def SetArgs(self, *args, **kwargs):
|
||||||
## """
|
"""
|
||||||
## (Re)set the args passed to the callable object. This is
|
(Re)set the args passed to the callable object. This is
|
||||||
## useful in conjunction with Restart if you want to schedule a
|
useful in conjunction with Restart if you want to schedule a
|
||||||
## new call to the same callable object but with different
|
new call to the same callable object but with different
|
||||||
## parameters.
|
parameters.
|
||||||
## """
|
"""
|
||||||
## self.args = args
|
self.args = args
|
||||||
## self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
|
|
||||||
|
|
||||||
## def HasRun(self):
|
def HasRun(self):
|
||||||
## return self.hasRun
|
return self.hasRun
|
||||||
|
|
||||||
## def GetResult(self):
|
def GetResult(self):
|
||||||
## return self.result
|
return self.result
|
||||||
|
|
||||||
## def Notify(self):
|
def Notify(self):
|
||||||
## """
|
"""
|
||||||
## The timer has expired so call the callable.
|
The timer has expired so call the callable.
|
||||||
## """
|
"""
|
||||||
## if self.callable and getattr(self.callable, 'im_self', True):
|
if self.callable and getattr(self.callable, 'im_self', True):
|
||||||
## self.runCount += 1
|
self.runCount += 1
|
||||||
## self.running = False
|
self.running = False
|
||||||
## self.result = self.callable(*self.args, **self.kwargs)
|
self.result = self.callable(*self.args, **self.kwargs)
|
||||||
## self.hasRun = True
|
self.hasRun = True
|
||||||
## if not self.running:
|
if not self.running:
|
||||||
## # if it wasn't restarted, then cleanup
|
# if it wasn't restarted, then cleanup
|
||||||
## wx.CallAfter(self.Stop)
|
wx.CallAfter(self.Stop)
|
||||||
|
|
||||||
## Interval = property(GetInterval)
|
Interval = property(GetInterval)
|
||||||
## Result = property(GetResult)
|
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