A modular Terminal User Interface (TUI) stopwatch application built with Python and the Textual framework. This application allows users to manage multiple independent stopwatches simultaneously within a responsive, keyboard-driven interface.
The Textual Stopwatch is designed to demonstrate efficient state management and reactive UI updates in a terminal environment. It features a custom component architecture where the stopwatch logic is decoupled from the main application layout, allowing for dynamic instantiation of widgets. Time tracking is handled via monotonic clocks to ensure accuracy.
- Multi-Instance Support: Users can dynamically add or remove stopwatch instances to the view.
- Accurate Timing: Utilizes
time.monotonicfor precise elapsed time calculation, independent of system clock updates. - Reactive Interface: Real-time UI updates handled by Textual's reactive attributes.
- Theme Support: Built-in toggle for dark and light modes.
- Responsive Layout: Uses a scrollable container to handle an arbitrary number of timers.
- CSS Styling: Interface styling is managed via a dedicated
.tcssfile for clear separation of logic and presentation.
The project follows a standard Python source structure. Based on the configuration, the logic is separated into the main application entry point and modular components.
├── src/
│ ├── app.py # Main application class and layout composition
│ ├── main.py # Entry point
│ ├── style.tcss # Textual CSS stylesheets
│ └── components/
│ ├── stopwatch.py # Stopwatch widget controller
│ └── timedisplay.py # Time calculation and display logic
├── pyproject.toml # Project configuration
├── uv.lock # Dependency lock file
└── README.md
- Python: Version 3.8 or higher.
- Package Manager: This project contains a
uv.lockfile, indicating it is managed byuv. However, standardpipcan also be used.
If you have uv installed, you can sync the project dependencies directly.
uv sync
Create a virtual environment and install the required textual dependency.
python -m venv .venv
source .venv/bin/activate # On Windows use: .venv\Scripts\activate
pip install textual
To start the application, execute the main.py file from the source directory:
uv run python src/main.py
The application supports mouse interaction for the Start, Stop, and Reset buttons. Additionally, global application state is managed via the following keyboard shortcuts:
| Key | Action | Description |
|---|---|---|
| A | Add Stopwatch | Instantiates and mounts a new stopwatch widget to the container. |
| R | Remove Stopwatch | Removes the last added stopwatch instance from the container. |
| D | Toggle Theme | Switches between Dark and Light mode. |
- Stopwatch (Widget): A container widget that acts as the controller. It manages the state of the buttons (Start/Stop/Reset) and communicates with the
TimeDisplaychild widget. - TimeDisplay (Static): A reactive widget responsible for calculating the time delta. It uses a set interval (10Hz) to update the
time_elapsedreactive variable, which triggers a redraw of the component string inHH:MM:SSformat.
The application utilizes style.tcss to define layout properties, such as docking positions for buttons and specific visibility rules based on the .started class state.