Create a Pomodoro Using Python Tkinter

The Pomodoro Technique is a time management method developed by Francesco Cirillo in the late 1980s. It uses 25-minute focused work sessions followed by short breaks to improve productivity. In this tutorial, we will create a functional Pomodoro timer using Python's Tkinter module.

What is Pomodoro?

Francesco Cirillo, a university student at the time, invented the Pomodoro Method in the late 1980s. Cirillo was having difficulty focusing on his academics and completing homework. He asked himself, feeling overwhelmed, to commit to only 10 minutes of dedicated study time. Inspired by the challenge, he discovered a tomato-shaped kitchen timer (pomodoro in Italian), and the Pomodoro technique was created.

Required Libraries

We will use Python's built-in modules for this project ?

import tkinter as tk
import time
import threading

Creating the GUI Window

First, let's create the main window and center it on the screen ?

import tkinter as tk
import time
import threading

# Create main window
root = tk.Tk()
root.title("Pomodoro Timer")

# Set window size and center it
window_width = 300
window_height = 200
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x_coordinate = int((screen_width / 2) - (window_width / 2))
y_coordinate = int((screen_height / 2) - (window_height / 2))
root.geometry(f"{window_width}x{window_height}+{x_coordinate}+{y_coordinate}")
root.resizable(False, False)

print("Window created and centered on screen")
Window created and centered on screen

Adding GUI Components

Now let's add labels and buttons to our timer interface ?

import tkinter as tk
import time
import threading

class PomodoroTimer:
    def __init__(self, root):
        self.root = root
        self.root.title("Pomodoro Timer")
        self.root.geometry("300x200")
        self.root.resizable(False, False)
        
        # Timer variables
        self.is_running = False
        self.time_left = 25 * 60  # 25 minutes in seconds
        
        # Current time label
        self.current_time_label = tk.Label(root, text="", font=("Arial", 14))
        self.current_time_label.pack(pady=10)
        
        # Timer display
        self.timer_label = tk.Label(root, text="25:00", font=("Arial", 30, "bold"))
        self.timer_label.pack(pady=10)
        
        # Button frame
        button_frame = tk.Frame(root)
        button_frame.pack(pady=10)
        
        # Start button
        self.start_button = tk.Button(button_frame, text="Start", font=("Arial", 12), 
                                      command=self.start_timer, width=8)
        self.start_button.pack(side="left", padx=5)
        
        # Stop button
        self.stop_button = tk.Button(button_frame, text="Stop", font=("Arial", 12), 
                                     command=self.stop_timer, width=8, state="disabled")
        self.stop_button.pack(side="right", padx=5)
        
        # Update current time
        self.update_current_time()
    
    def update_current_time(self):
        current_time = time.strftime("%H:%M:%S")
        self.current_time_label.config(text=f"Current Time: {current_time}")
        self.root.after(1000, self.update_current_time)
    
    def start_timer(self):
        self.is_running = True
        self.start_button.config(state="disabled")
        self.stop_button.config(state="normal")
        self.countdown()
    
    def stop_timer(self):
        self.is_running = False
        self.time_left = 25 * 60
        self.timer_label.config(text="25:00")
        self.start_button.config(state="normal")
        self.stop_button.config(state="disabled")
    
    def countdown(self):
        if self.is_running and self.time_left > 0:
            minutes = self.time_left // 60
            seconds = self.time_left % 60
            self.timer_label.config(text=f"{minutes:02d}:{seconds:02d}")
            self.time_left -= 1
            self.root.after(1000, self.countdown)
        elif self.time_left == 0:
            self.timer_label.config(text="Time's Up!")
            self.start_button.config(state="normal")
            self.stop_button.config(state="disabled")
            self.is_running = False
            print("Pomodoro session completed!")

# Create and run the application
root = tk.Tk()
app = PomodoroTimer(root)
print("Pomodoro Timer created successfully")
Pomodoro Timer created successfully

Complete Pomodoro Timer Application

Here's the complete working Pomodoro timer with all features ?

import tkinter as tk
import time
from tkinter import messagebox

class PomodoroTimer:
    def __init__(self, root):
        self.root = root
        self.root.title("Pomodoro Timer")
        
        # Center the window
        window_width = 350
        window_height = 250
        screen_width = root.winfo_screenwidth()
        screen_height = root.winfo_screenheight()
        x = int((screen_width / 2) - (window_width / 2))
        y = int((screen_height / 2) - (window_height / 2))
        root.geometry(f"{window_width}x{window_height}+{x}+{y}")
        root.resizable(False, False)
        
        # Timer variables
        self.is_running = False
        self.time_left = 25 * 60  # 25 minutes
        self.session_count = 0
        
        # GUI Components
        self.setup_gui()
        self.update_current_time()
    
    def setup_gui(self):
        # Title
        title_label = tk.Label(self.root, text="? Pomodoro Timer", 
                              font=("Arial", 16, "bold"))
        title_label.pack(pady=10)
        
        # Current time
        self.current_time_label = tk.Label(self.root, text="", 
                                          font=("Arial", 12))
        self.current_time_label.pack()
        
        # Timer display
        self.timer_label = tk.Label(self.root, text="25:00", 
                                   font=("Arial", 36, "bold"), 
                                   fg="red")
        self.timer_label.pack(pady=15)
        
        # Session counter
        self.session_label = tk.Label(self.root, text="Sessions: 0", 
                                     font=("Arial", 12))
        self.session_label.pack()
        
        # Buttons
        button_frame = tk.Frame(self.root)
        button_frame.pack(pady=15)
        
        self.start_button = tk.Button(button_frame, text="? Start", 
                                     font=("Arial", 12), bg="green", 
                                     fg="white", command=self.start_timer)
        self.start_button.pack(side="left", padx=5)
        
        self.stop_button = tk.Button(button_frame, text="? Stop", 
                                    font=("Arial", 12), bg="red", 
                                    fg="white", command=self.stop_timer, 
                                    state="disabled")
        self.stop_button.pack(side="left", padx=5)
        
        self.reset_button = tk.Button(button_frame, text="? Reset", 
                                     font=("Arial", 12), bg="orange", 
                                     fg="white", command=self.reset_timer)
        self.reset_button.pack(side="left", padx=5)
    
    def update_current_time(self):
        current_time = time.strftime("%H:%M:%S")
        self.current_time_label.config(text=f"Current Time: {current_time}")
        self.root.after(1000, self.update_current_time)
    
    def start_timer(self):
        self.is_running = True
        self.start_button.config(state="disabled")
        self.stop_button.config(state="normal")
        self.timer_label.config(fg="green")
        self.countdown()
    
    def stop_timer(self):
        self.is_running = False
        self.start_button.config(state="normal")
        self.stop_button.config(state="disabled")
        self.timer_label.config(fg="red")
    
    def reset_timer(self):
        self.is_running = False
        self.time_left = 25 * 60
        self.timer_label.config(text="25:00", fg="red")
        self.start_button.config(state="normal")
        self.stop_button.config(state="disabled")
    
    def countdown(self):
        if self.is_running and self.time_left > 0:
            minutes = self.time_left // 60
            seconds = self.time_left % 60
            time_display = f"{minutes:02d}:{seconds:02d}"
            self.timer_label.config(text=time_display)
            
            # Change color when time is running low
            if self.time_left <= 300:  # Last 5 minutes
                self.timer_label.config(fg="orange")
            if self.time_left <= 60:   # Last minute
                self.timer_label.config(fg="red")
            
            self.time_left -= 1
            self.root.after(1000, self.countdown)
        
        elif self.time_left == 0 and self.is_running:
            # Timer finished
            self.timer_label.config(text="Time's Up!", fg="red")
            self.session_count += 1
            self.session_label.config(text=f"Sessions: {self.session_count}")
            self.start_button.config(state="normal")
            self.stop_button.config(state="disabled")
            self.is_running = False
            
            # Show completion message
            messagebox.showinfo("Pomodoro Complete", 
                               "Great job! Take a 5-minute break.")
            
            # Reset for next session
            self.time_left = 25 * 60
            self.timer_label.config(text="25:00", fg="red")

# Create and run the application
if __name__ == "__main__":
    root = tk.Tk()
    app = PomodoroTimer(root)
    root.mainloop()
    print("Pomodoro Timer application started!")
Pomodoro Timer application started!

Key Features

Our Pomodoro timer includes several useful features ?

  • Visual Timer: Large, easy-to-read countdown display
  • Color Coding: Timer changes color as time runs low
  • Session Counter: Tracks completed Pomodoro sessions
  • Current Time Display: Shows real-time clock
  • Control Buttons: Start, Stop, and Reset functionality
  • Completion Alert: Pop-up notification when session ends

How It Works

The timer uses Tkinter's after() method to update the display every second without blocking the GUI. The countdown() method recursively calls itself until the timer reaches zero, then displays a completion message and resets the interface for the next session.

Conclusion

This Pomodoro timer demonstrates practical GUI programming with Tkinter, combining time management principles with Python programming. You can extend this application by adding break timers, sound notifications, or productivity statistics tracking.

Updated on: 2026-03-27T16:18:31+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements