Introduction

Many GUI programs (especially games) feature a stopwatch to track time. This snippet demonstrates the basics of how to use a wx.StopWatch in an application.

What Objects are Involved

Process Overview

Once launched, this recipe shows a window titled "Hello World!", which consists of four buttons and a status bar. The status bar initially reads "Ready" and changes its message with each click of a button. A semaphore is used to keep track of the stopwatch mode.

Special Concerns

Code Sample

   1 #! /usr/bin/env python
   2 ## 
   3 ## DO NOT EDIT 
   4 ##
   5 #----------------------------------------------------------------------#
   6 # This is a minimal wxPython program featuring a StopWatch widget.
   7 #
   8 # Tian Xie
   9 # 3/8/2005
  10 #----------------------------------------------------------------------#
  11 
  12 import wx
  13 
  14 class MyGUI(wx.Frame):
  15     """Hello World!
  16 
  17     Once stopped, a typical stopwatch reports total time elapsed since
  18     started. A stopwatch can be paused after started and time won't be
  19     recorded until it's resumed. A paused stopwatch must be resumed.
  20     """
  21     def __init__(self, parent, title):
  22         # Create a non-resizable frame.
  23         wx.Frame.__init__(self, parent, title=title, style=wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER)
  24         
  25         # Simulate a stopwatch with four buttons.
  26         StartButton = wx.Button(self, -1, "Start")
  27         PauseButton = wx.Button(self, -1, "Pause")
  28         ResumButton = wx.Button(self, -1, "Resume")
  29         Stop_Button = wx.Button(self, -1, "Stop!")
  30 
  31         # A status bar displays current stopwatch mode.
  32         self.CreateStatusBar()
  33         self.SetStatusText("Ready.")
  34         
  35 #----------------------------------------------------------------------#
  36 # Put more GUI code here for a fancier application.
  37 #----------------------------------------------------------------------#
  38 
  39         # Use a plain sizer for the layout.
  40         MyBS = wx.BoxSizer(wx.HORIZONTAL)
  41         # Each non-resizable button has roomy borders (10 pixels).
  42         MyBS.Add(StartButton, 0, wx.ALL, 10)
  43         MyBS.Add(PauseButton, 0, wx.ALL, 10)
  44         MyBS.Add(ResumButton, 0, wx.ALL, 10)
  45         MyBS.Add(Stop_Button, 0, wx.ALL, 10)
  46         
  47         self.SetSizerAndFit(MyBS)
  48 
  49         # Create a stopwatch.
  50         self.MySW = wx.StopWatch()
  51         # Set its initial mode to be "stopped".
  52         self.semaphore = 0
  53 
  54         self.Bind(wx.EVT_BUTTON, self.onStart, StartButton)
  55         self.Bind(wx.EVT_BUTTON, self.onPause, PauseButton)
  56         self.Bind(wx.EVT_BUTTON, self.onResum, ResumButton)
  57         self.Bind(wx.EVT_BUTTON, self.onStop_, Stop_Button)
  58 #----------------------------------------------------------------------#
  59         
  60     def onStart(self, evt):
  61         if self.semaphore == 0:
  62             self.MySW.Start()
  63             self.semaphore = 2 # Set the mode to be "started".
  64             message = "Go!"
  65         else:
  66             message = "Hold. I've been started already."
  67         self.SetStatusText(message)
  68 #----------------------------------------------------------------------#
  69 
  70     def onPause(self, evt):
  71         if self.semaphore > 0: # A stopwatch was resumed or started.
  72             self.MySW.Pause()
  73             self.semaphore = -1 # Set the mode to be "paused".
  74             message = "Freeze!"
  75         else:
  76             message = "I cannot pause because I'm still."
  77         self.SetStatusText(message)
  78 #----------------------------------------------------------------------#
  79 
  80     def onResum(self, evt):
  81         if self.semaphore == -1:
  82             self.MySW.Resume()
  83             self.semaphore = 1 # Set the mode to be "resumed".
  84             message = "I'm ticking again."
  85         else:
  86             message = "I cannot resume because I'm not paused."
  87         self.SetStatusText(message)
  88 #----------------------------------------------------------------------#
  89 
  90     def onStop_(self, evt):
  91         if self.semaphore > 0:
  92             message = str(self.MySW.Time()) + " milliseconds recorded."
  93             self.semaphore = 0
  94         else:
  95             message = "I cannot stop because I'm still."
  96         self.SetStatusText(message)
  97 #----------------------------------------------------------------------#
  98 
  99 
 100 app = wx.App()
 101 frame = MyGUI(None, "Hello World!")
 102 frame.Show()
 103 app.MainLoop()

Comments

Please test this program on other platforms or versions. If it doesn't work, find a fix and correct it here. Thanks.

I wonder how to implement a stopwatch without a semaphore.

Reference

wx.StopWatch

StopWatch (last edited 2010-01-17 18:50:29 by 79-65-133-135)

NOTE: To edit pages in this wiki you must be a member of the TrustedEditorsGroup.