wxPython in Action (wx.Timer)

  18.5 使用wx.Timer来设置定时事件

有时你需要让你的应用程序产生基于时间段的事件。要得到这个功能,你可以使用类wx.Timer。

18.5.1 产生EVT_TIMER事件

对wx.Timer最灵活和最有效的用法是使它产生EVT_TIMER,并将该事件如同其它事件一样进行绑定。

创建定时器

要创建一个定时器,首先要使用下面的构造器来创建一个wx.Timer的实例。

wx.Timer(owner=None,  id=-1)

其中参数owner是实现wx.EvtHandler的实例,即任一能够接受事件通知的wxPython控件或其它的东西。参数id用于区分不同的定时器。如果没有指定id,则wxPython会为你生成一个id号。如果当你创建定时器时,你不想设置参数owner和id,那么你可以以后随时使用SetOwner(owner=None,  id=-1)方法来设置,它设置同样的两个参数。

绑定定时器

在你创建了定时器之后,你可以如下面一行的代码来在你的事件处理控件中绑定wx.EVT_TIMER事件。

self.Bind(wx.EVT_TIMER,  self.OnTimerEvent)

如果你需要绑定多个定时器到多个处理函数,你可以给Bind函数传递每个定时器的ID,或将定时器对象作为源参数来传递。

timer1  =  wx.Timer(self) 
timer2  =  wx.Timer(self) 
self.Bind(wx.EVT_TIMER,  self.OnTimer1Event,  timer1) 
self.Bind(wx.EVT_TIMER,  self.OnTimer2Event,  timer2) 

启动和停止定时器

在定时器事件被绑定后,你所需要做的所有事情就是启动该定时器,使用方法Start(milliseconds=-1,  oneShot=False)。其中参数milliseconds是毫秒数。这将在经过milliseconds时间后,产生一个wx.EVT_TIMER事件。如果milliseconds=-1,那么将使用早先的毫秒数。如果oneShot为True,那么定时器只产生wx.EVT_TIMER事件一次,然后定时器停止。否则,你必须显式地使用Stop()方法来停止定时器。
例18.4使用了定时器机制来驱动一个数字时钟,并每秒刷新一次显示。

例18.4 一个简单的数字时钟

#-*-  encoding:UTF-8  -*-
import  wx
import  time

class  ClockWindow(wx.Window):
        def  __init__(self,  parent):
                wx.Window.__init__(self,  parent)
                self.Bind(wx.EVT_PAINT,  self.OnPaint)
                self.timer  =  wx.Timer(self)#创建定时器
                self.Bind(wx.EVT_TIMER,  self.OnTimer,  self.timer)#绑定一个定时器事件
                self.timer.Start(1000)#设定时间间隔

        def  Draw(self,  dc):#绘制当前时间
                t  =  time.localtime(time.time())
                st  =  time.strftime("%I:%M:%S",  t)
                w,  h  =  self.GetClientSize()
                dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
                dc.Clear()
                dc.SetFont(wx.Font(30,  wx.SWISS,  wx.NORMAL,  wx.NORMAL))
                tw,  th  =  dc.GetTextExtent(st)
                dc.DrawText(st,  (w-tw)/2,  (h)/2  -  th/2)
               
        def  OnTimer(self,  evt):#显示时间事件处理函数
                dc  =  wx.BufferedDC(wx.ClientDC(self))
                self.Draw(dc)

        def  OnPaint(self,  evt):
                dc  =  wx.BufferedPaintDC(self)
                self.Draw(dc)

class  MyFrame(wx.Frame):
        def  __init__(self):
                wx.Frame.__init__(self,  None,  title="wx.Timer")
                ClockWindow(self)       

app  =  wx.PySimpleApp()
frm  =  MyFrame()
frm.Show()
app.MainLoop()

确定当前定时器的状态

你可以使用方法IsRunning()来确定定时器的当前状态,使用方法GetInterval()来得到当前的时间间隔。如果定时器正在运行并且只运行一次的话,方法IsOneShot()返回True。

wx.TimerEvent几乎与它的父类wx.Event是一样的,除了它不包括wx.GetInterval()方法来返回定时器的时间间隔外。万一你将来自多个定时器的事件绑定给了相同的处理函数,并希望根据特定的定时器的事件来做不同的动作的话,可使用事件方法GetId()来返回定时器的ID,以区别对待。

18.5.2 学习定时器的其它用法

另一种使用定时器的方法是子类化wx.Timer。在你的子类中你可以覆盖方法Notify()。在父类中,该方法每次在定时器经过指定的时间间隔后被自动调用,它触发定时器事件。然而你的子类没有义务去触发一个定时器事件,你可以在该Notify()方法中做你想做的事,以响应定时器的时间间隔。

要在未来某时触发一个特定的行为,有一个被称为wx.FutureCall的类可以使用。它的构造器如下:

wx.FutureCall(interval,  callable,  *args,  **kwargs)

一旦它被创建后,wx.FutureCall的实例将等待interval毫秒,然后调用传递给参数callable的对象,参数*args,  **kwargs是callable中的对象所要使用的。wx.FutureCall只触发一次定时事件。

你可能感兴趣的:(wxPython in Action (wx.Timer))