Skip to main content

Countdown Timer with Tkinter: Python Programming

 


Master Python GUIs: Build a Sleek Countdown Timer with Tkinter ⏱️


Introduction

Are you tired of boring, command-line scripts? It’s time to level up your Python skills by building a Graphical User Interface (GUI). Today, we are building a "Focus Timer"—a fully functional, aesthetically pleasing countdown timer using Python’s built-in Tkinter library.

Whether you want to use the Pomodoro technique or just need a reminder to stretch, this project is the perfect way to learn about event loops, UI styling, and state management in Python.

Why This Project Rocks

  • Modern UI: We ditch the default "gray" look for a sleek Dark Mode.

  • User-Friendly: Simple input fields for Hours, Minutes, and Seconds.

  • Real-World Logic: Learn how to handle time without freezing your app using the .after() method.


The Code

Copy the code below into your favorite IDE (like VS Code or PyCharm) and run it.

Python
import tkinter as tk
from tkinter import messagebox

class AttractiveTimer:
    def __init__(self, root):
        self.root = root
        self.root.title("Focus Timer")
        self.root.geometry("400x450")
        self.root.resizable(False, False)
        
        # --- Color Palette (Dark Mode) ---
        self.bg_color = "#2C3E50"      # Dark Blue-Gray
        self.text_color = "#ECF0F1"    # Off-White
        self.accent_color = "#E74C3C"  # Alizarin Red (for display)
        self.btn_color = "#27AE60"     # Green (Start)
        self.stop_color = "#C0392B"    # Dark Red (Stop)

        self.root.configure(bg=self.bg_color)

        # --- Variables ---
        self.time_left = 0
        self.running = False
        
        # --- UI Layout ---
        self.create_widgets()

    def create_widgets(self):
        # 1. Title Label
        title_label = tk.Label(self.root, text="FOCUS TIMER", font=("Helvetica", 24, "bold"),
                               bg=self.bg_color, fg=self.text_color)
        title_label.pack(pady=20)

        # 2. Time Display (Big Numbers)
        self.display_label = tk.Label(self.root, text="00:00:00", font=("Digital-7", 48, "bold"),
                                      bg=self.bg_color, fg=self.accent_color)
        self.display_label.pack(pady=10)

        # 3. Input Frame
        input_frame = tk.Frame(self.root, bg=self.bg_color)
        input_frame.pack(pady=20)

        # Input Helper Function
        def create_entry(placeholder):
            entry = tk.Entry(input_frame, width=5, font=("Arial", 14), justify='center')
            entry.insert(0, placeholder)
            return entry

        self.hour_entry = create_entry("00")
        self.minute_entry = create_entry("00")
        self.second_entry = create_entry("00")

        # Labels for inputs
        tk.Label(input_frame, text="H", bg=self.bg_color, fg=self.text_color).grid(row=0, column=0, padx=5)
        self.hour_entry.grid(row=1, column=0, padx=5)
        
        tk.Label(input_frame, text="M", bg=self.bg_color, fg=self.text_color).grid(row=0, column=1, padx=5)
        self.minute_entry.grid(row=1, column=1, padx=5)
        
        tk.Label(input_frame, text="S", bg=self.bg_color, fg=self.text_color).grid(row=0, column=2, padx=5)
        self.second_entry.grid(row=1, column=2, padx=5)

        # 4. Control Buttons
        btn_frame = tk.Frame(self.root, bg=self.bg_color)
        btn_frame.pack(pady=20)

        self.start_btn = tk.Button(btn_frame, text="Start", font=("Arial", 12, "bold"),
                                   bg=self.btn_color, fg="white", width=10, command=self.start_timer)
        self.start_btn.grid(row=0, column=0, padx=10)

        self.stop_btn = tk.Button(btn_frame, text="Reset", font=("Arial", 12, "bold"),
                                  bg=self.stop_color, fg="white", width=10, command=self.reset_timer)
        self.stop_btn.grid(row=0, column=1, padx=10)

    def start_timer(self):
        if not self.running:
            try:
                h = int(self.hour_entry.get())
                m = int(self.minute_entry.get())
                s = int(self.second_entry.get())
                self.time_left = h * 3600 + m * 60 + s
                
                if self.time_left > 0:
                    self.running = True
                    self.count()
                else:
                    messagebox.showwarning("Invalid Time", "Please enter a valid time!")
            except ValueError:
                messagebox.showerror("Error", "Please enter numeric values only.")

    def count(self):
        if self.running and self.time_left > 0:
            # Calculate hours, minutes, seconds
            mins, secs = divmod(self.time_left, 60)
            hours, mins = divmod(mins, 60)
            
            # Update format
            time_format = '{:02d}:{:02d}:{:02d}'.format(hours, mins, secs)
            self.display_label.config(text=time_format)
            
            self.time_left -= 1
            # Recursively call this function after 1000ms (1 second)
            self.root.after(1000, self.count)
            
        elif self.time_left == 0 and self.running:
            self.display_label.config(text="00:00:00")
            self.running = False
            messagebox.showinfo("Time's Up!", "Your countdown has finished.")

    def reset_timer(self):
        self.running = False
        self.time_left = 0
        self.display_label.config(text="00:00:00")
        self.hour_entry.delete(0, tk.END); self.hour_entry.insert(0, "00")
        self.minute_entry.delete(0, tk.END); self.minute_entry.insert(0, "00")
        self.second_entry.delete(0, tk.END); self.second_entry.insert(0, "00")

if __name__ == "__main__":
    root = tk.Tk()
    app = AttractiveTimer(root)
    root.mainloop()

How It Works (The Technical Part)

If you are new to Tkinter, here are the key concepts we used:

  1. Grid Layout Manager: Instead of guessing coordinates, we used .grid() and .pack() to automatically center the buttons and input fields.

  2. The .after() Method: This is the secret sauce. You cannot use a standard time.sleep() loop in a GUI because it will "freeze" the window (making buttons clicked unresponsive). Instead, we use root.after(1000, self.count), which tells Python: "Wait 1000 milliseconds, then run the count function again."

  3. Formatting with divmod: We used the built-in divmod function to cleanly convert total seconds back into Hours, Minutes, and Seconds for the display.

Next Steps: Make It Yours!

Don't stop here. Try adding these features to customize your app:

  • Add Sound: Use the playsound library to play an alarm when the timer hits zero.

  • Progress Bar: Add a visual bar that shrinks as time runs out.

  • Executable: Use pyinstaller to turn this script into a .exe file you can send to friends.


Comments

Popular posts from this blog

Simple Number Guessing Game in Python

  Build a Simple Number Guessing Game in Python: A Beginner-Friendly Project Are you looking to dive into Python programming with a fun and interactive project? The number guessing game Python project is an excellent starting point for beginners. This classic game challenges players to guess a randomly generated number within a limited number of attempts, helping you practice essential concepts like loops, conditionals, and user input. In this blog post, we'll walk through how to create your own Python guessing game project , complete with code and detailed explanations. Whether you're a student, hobbyist, or aspiring developer, this tutorial will boost your skills while keeping things engaging. Why Choose a Number Guessing Game as Your Python Project? The number guessing game Python is one of the most searched beginner projects because it's simple yet versatile. It teaches core programming fundamentals without overwhelming you with complex libraries or frameworks. Her...

Classic Number Guessing Game Using Python

    Build Your First Python Game: The Classic Number Guessing Game! Are you learning Python and looking for a fun, hands-on project to test your skills? You’ve come to the right place. When starting out with programming, it’s easy to get stuck just reading tutorials. The real magic happens when you build something interactive. Today, we’re going to build a classic: The Number Guessing Game . It’s simple concept: The computer picks a random number between 1 and 100, and you have a limited number of tries to guess it. After every guess, the computer tells you if you need to go "Higher" or "Lower." Why This is the Perfect Beginner Project Despite its simplicity, this game is a fantastic learning tool because it combines several fundamental programming concepts into one cohesive package. By building this, you will master: Variables: Storing information like the secret number and attempts left. Loops ( while ): Keeping the game running until the player wins or loses. C...

Python GUI Program to Calculate Age

Python GUI Program to Calculate Age     Certainly! Below is a Python program using the tkinter library to create a simple GUI that accepts a date of birth and calculates the age.   import tkinter as tk from tkinter import messagebox from datetime import datetime def calculate_age():     dob_str = entry_dob.get()     try:         dob = datetime.strptime(dob_str, "%Y-%m-%d")         today = datetime.today()         age = today.year - dob.year - ((today.month, today.day) < (dob.month, dob.day))         messagebox.showinfo("Age Calculator", f"Your age is: {age} years")     except ValueError:         messagebox.showerror("Error", "Please enter the date in YYYY-MM-DD format") # Create the main window root = tk.Tk() root.title("Age Calculator") # Create a labe...