A multiple timer application in Python/wxPython

This project implements a multiple timer application. It was written in
  1. Python 3.8.2
  2. wxPython 4.1.0

Feel free to experiment. Here are some possible enhancements:

  1. Add the ability to run a program when the timer expires. With a little scripting you could, for example, schedule the sending of an email.
  2. Add the option to auto-restart a timer after it has alarmed.
  3. Autosave timers on close and reload them on restart.
  4. Add a taskbar icon with pop-up summary of timers on mouse over.
The Files:
Timer.pyw

This file contains the mainline GUI code. It displays a list of custom timer entries and three control buttons. The three buttons allow the user to:

  1. create a new timer
  2. start all existing timers
  3. stop all existing timers

Timer entries are displayed one per line. Each timer contains the following controls:

  1. a button which will run/stop the timer
  2. a button that will stop and reset the timer (countdown only)
  3. a button that will delete a timer
  4. a checkbox to enable a popup message when the timer expires
  5. display of the time remaining
  6. description of the timer
TimerEntry.py

This is a custom control that is subclassed from a wx.BoxSizer. The fields mentioned above are arranged horizontally in this sizer.

A timer entry object can delete all of the controls within it, however, it is up to the parent object to delete the actual timer entry object. I decided that the easiest way to do this was to pass the TimerEntry constructor the address of a delete method from the parent object.

Countdown timers are updated once per second by subtracting one second from the time remaining. Absolute timers, however, must recalculate the time remaining on every timer event otherwise, if you put the computer to sleep then wake it up the time remaining would not account for the sleep period.

TimerDialog.py

This is a custom control that is subclassed from wx.Dialog. This control displays a GUI where the user can select a timer type (absolute or countdown), and specify timer values and a description. For absolute timers, the values entered represent an absolute date/time at which the alarm is to sound. Countdown timers represent a time span after which the alarm will sound. The dialog offers three closing options:

  1. Create - creates the timer but does not start it
  2. Create & Run - creates the timer and automatically starts it
  3. Cancel - does not create a timer
GetMutex.py

This module is used to ensure that only one copy of Timer.pyw can run at a time. It does this by creating a mutex which uses the app name (Timer.pyw) as the mutex prefix. If you want to be able to run multiple copies you can remove the lines:

from GetMutex import *
if (single := GetMutex()).AlreadyRunning(): 
    wx.MessageBox(__file__ + " is already running", __file__, wx.OK)
    sys.exit()
alarm.wav

This is the wav file that will be played whenever a timer expires. If you do not like the one provided just copy a wav file of your choice to a file of the same name.

The entire project is attached as a zip file.