DEV Community

Buzzpy 💡
Buzzpy 💡

Posted on • Originally published at

Make your own Pomodoro Application with Python

Image description
Hello buzzdies! I bet, most of you have heard enough about Pomodoro Technique, a time management method. In case you haven’t, lemme explain.

The Pomodoro technique is invented by Francesco Cirillo, around the 1980s. It encourages people to work with the time they have—rather than against it. Using this method, you break your workday into 25-minute chunks separated by five-minute breaks. These intervals are referred to as “Pomodoro”. The diagram below explains it further.

Image description


This technique is for everyone, including programmers and developers as well. But working according to Pomodoro using a regular clock or alarms is very disturbing so it’s always better to have some software. And it’s much better if we can develop the software ourselves!

Yup, you got the point. This tutorial is on how to make a Pomodoro Application using Python, with User Interface. Move on 😉

In case you're in a hurry, the source code can be found in this GitHub repository. Open for PRs!

Visit Github Repo

Getting Started

First, we should import the libraries— math for calculations and tkinter for GUI. Since these are pre-installed, we can import them directly.

From tkinter import *
Import math
Enter fullscreen mode Exit fullscreen mode

Basic UI

Interesting part first, let’s build the user interface.

Defining Global Constants

When working GUI, it’s a good practice to define global constants for properties like Color, Font types and sizes and etc. The following code does the job.

PINK = "#f81365"
RED = "#e7305b"
GREEN = "#9bdeac"
FONT_NAME = "Barlow Condensed"
Enter fullscreen mode Exit fullscreen mode

Setting Up

We’re going to use an ordinary Tkinter window, size 100 x 50. And the constant variables we declared in the previous part are used here.

window = Tk()
window.config(padx=100, pady=50, bg=GRAY)
title_label = Label(text="Timer", fg=PINK, bg=GRAY, font=("Barlow Condensed", 50))
title_label.grid(column=1, row=0)
canvas = Canvas(width=200, height=224, bg=GRAY, highlightthickness=0)
# highlightthicknes is used for making the highlight disappear
tomato_img = PhotoImage(file="tomato.png")# use your path
canvas.create_image(100, 100, image=tomato_img)
timer_text = canvas.create_text(100, 110, text="00:00", fill="black", font=("Barlow Condensed", 35, "bold"))
canvas.grid(column=1, row=1)
# count_down(5)
# x and y values are half of the width and the height
start_button = Button(text="Start", highlightthickness=0, command=start_timer, bg=PINK, font=("Barlow Condensed", 10))
start_button.grid(column=0, row=2)
reset_button = Button(text="Reset", highlightthickness=0, command = reset_timer, bg=PINK, font=(FONT_NAME, 10))
reset_button.grid(column=2, row=2)

check_marks = Label(text="", fg=GREEN, bg=GRAY)
check_marks.grid(column=1, row=3)

Enter fullscreen mode Exit fullscreen mode

You may have seen that we used an Image of a Tomato in the above code. The image can be downloaded from the GitHub repository

Don’t hurry to test this code as it’s not ready yet! There are some functions and variables which aren’t been declared yet. So it is time to move to the next part,

Declaring Functions

First, we will finish the logical part. Here, we need three major functions. reset_timer start_timer countdown

Let’s start with the Reset function. But before that, we need to declare some more values as global constants, like below:

reps = 0
timer = None

Enter fullscreen mode Exit fullscreen mode

Note: the value reps is used for governing the timing section of work and breaks and counting them.



In this function, we need to do to following things: Reset the timer text to 00:00 Cancel the timer Reset reps to 0 Delete the checkmark(used for counting no: of working time sections) We use the following code to do all of these.

def reset_timer():
   canvas.itemconfig(timer_text, text="00:00")
   global reps
   reps = 0
Enter fullscreen mode Exit fullscreen mode

Awesome! Now let’s move to the next part.


Compared to the Reset function, the Start function is somewhat lengthy as it does some more tasks, such as below:

  • Add +1 to reps the variable Defining Long breaks and Short breaks.
  • Converting minutes to seconds

The following code can do all the above:

def start_timer():
   global reps
   reps += 1
   work_sec = WORK_MIN * 60
   short_break_sec = SHORT_BREAK_MIN * 60
   long_break_sec = LONG_BREAK_MIN * 60

   if reps % 8 == 0:     # If it's the 8th rep
       title_label.config(text="Break", fg=RED)

   elif reps % 2 == 0:     # If it's the 2nd/4th/6th rep
       title_label.config(text="Break", fg=PINK)

       title_label.config(text="Work", fg=PINK)

Enter fullscreen mode Exit fullscreen mode

Awesome! But we’re not ready yet, we have to write another function for counting down.


In this function, we need to do the following tasks:

  • Count down and change the text accordingly.
  • Put check marks for each work session.

Here’s the code we can use for these purposes.

def count_down(count):
   count_min = math.floor(count / 60)
   count_sec = count % 60

   if count_sec < 10:
       count_sec = f"0{count_sec}"
   canvas.itemconfig(timer_text, text=f"{count_min}:{count_sec}")
   if count > 0:
       global timer
       timer = window.after(1000, count_down, count - 1)
       marks = ""
       work_sessions = math.floor(reps/2)
       for _ in range(work_sessions):
           marks += "✓"
Enter fullscreen mode Exit fullscreen mode

Awesome! Believe it or not, we’re done with our Pomodoro Application. Here are some screenshots how what it looks like:

Default Window

Image description


Image description

On break...

Image description


In this short tutorial, we created an awesome-looking and simple Pomodoro application that can boost your productivity at work. The source code can be found in below GitHub repository,

View Repository
Don’t forget to fork, star, and contribute! Also if you have any questions or feedback, drop them in the comments.

Happy Coding!

Enjoyed the article? Make sure to subscribe to "The Buzzletter" so you will never miss any of my content + any gifts I offer! 🐳

Image description

Top comments (3)

growingwings profile image
Peter Hegedus

I love this!
Just a minor detail: it was a bit confusing for me as someone new to tkinter that we have prepared the window first and then defined the functions, as the buttons apparently need their command functions to be defined before their own definitions. I got an error before realizing I need to switch up the two.

buzzpy profile image
Buzzpy 💡

Oh, it took me a while to notice that. I had already written that code when I wrote this tutorial and must've missed that point!

Thanks a bunch! I will try to edit that 💙

sreno77 profile image
Scott Reno

This is awesome! I'll have to try this out.