Build Digital & Analog Clock GUI with Python Tkinter

analog-and-digital-clock-in-python-tkinter-with-source-code

Another Python project! In this tutorial, I will show you how to make both Digital and Analog clock GUIs in Python using the Tkinter library. These clock apps will run in real-time. In this example, we will see how to create a stylish clock using the Tkinter library of Python.

Understand Tkinter Library

Tkinter is a graphical user interface (GUI) library for Python that offers a range of elements to choose from. It is one of the popular libraries to make desktop applications using Python.

If you are new to the Tkinter library I will highly recommend you read this tutorial before moving forward.

Digital Clock GUI in Python using Tkinter

Making a digital clock is very easy and straightforward. The below code is to make a digital clock in Python using the Tkinter library:

# digital clock in python tkinter
import tkinter as tk
import time

# Create the main window
root = tk.Tk()
# Title of the Tkinter Application
root.title("Digital Clock")

# Update clock display time
def time_update():
    current_time = time.strftime("%H:%M:%S")
    clock.config(text=current_time)
    clock.after(1000, time_update)

# clock canvas
clock = tk.Label(root, font=("times", 50, "bold"), bg="white")
# Add the clock label to the main window
clock.pack(fill="both", expand=True)

time_update()
root.mainloop()
digital clock in python tkinter

In the above code:

  • time_update function is to update the time each second (1000 milliseconds)
  • In line 17, we are creating a label to display the clock time on the white background
  • At line 21 we are calling time_update function to run our real-time digital clock in the Tkinter canvas
  • Finally, at line 22, we are calling the mainloop() function to launch the application

Note that this is an example digital clock to show time in the 24-Hour time format.

Creating the Analog Clock GUI

Making an analog clock with Tkinter is slightly more complex than a digital clock. But no need to worry, I will explain each step in detail so that you can understand each part of it.

The concept of making an analog clock is to draw the clock on a Tkinter canvas and then each second change the drawing. A basic analog clock has three hands:

  1. Hour hand: Update the drawing each hour
  2. Minute hand: Update the drawing each minute
  3. Second hand: Update the drawing each second

Since the second hand is changing its position each second, we need to update our clock drawing each second.

Steps to building an Analog clock in Python using Tkinter:

Step1: Create a clock Canvas

At the very first step, we will create the canvas for our clock. For this example clock project, I am going to create a clock canvas size of 400×400 pixels with white background. Below code is to do that.

import tkinter as tk
import time
import math

# Height and width of Analog clock window
WIDTH = 400
HEIGHT = 400

root = tk.Tk()
root.title("Analog Clock")

# Create clock canvas tkinter
canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="white")
canvas.pack()

root.mainloop()
analog-clock-canvas-in-tkinter-python
Analog clock canvas

Step2: Define the clock update function

Now we need to write a clock update function. This is the heart of our Tkinter analog clock. This function will update the clock display on the canvas every second.

Also Read:  How to create a GUI calculator in Python using Tkinter

We need to mention everything inside this function. So I decided to break the entire update_clock function into some steps:

2.1 Create time variabel

# Import Tkinter library
import tkinter as tk
import time
import math

# # Height and width of Analog clock window
WIDTH = 400
HEIGHT = 400

root = tk.Tk()
# Application name
root.title("Analog Clock")
canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="white")
canvas.pack()

def update_clock():
    canvas.delete("all")
    now = time.localtime()
    hour = now.tm_hour % 12
    minute = now.tm_min
    second = now.tm_sec

    # Draw clock face
    canvas.create_oval(2, 2, WIDTH, HEIGHT, outline="black", width=2)
    
# Calling the function
update_clock()

# Running main loop to run the tkinter application
root.mainloop()
drawing-analog-clock-face-in-tkinter-python-oval-or-circular

Here in this code:

  • canvas.delete("all") clears all previous drawings from the canvas
  • time.localtime() is to fetch the current time from your system
  • hour, minute, and second are variables that extract the hour, minute, and second from the time structure variable now
  • canvas.create_oval(2, 2, WIDTH, HEIGHT, outline="black", width=2) draws an oval outline for the clock face

2.2: Draw Hour Numbers

Now we need to draw hour numbers ie: 1, 2, 3, …,12 in our analog clock. Let’s do that in the below code. So our updated function code will will looks like below:

import tkinter as tk
import time
import math

WIDTH = 400
HEIGHT = 400

root = tk.Tk()
root.title("Analog Clock")
canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="white")
canvas.pack()

def update_clock():
    canvas.delete("all")
    now = time.localtime()
    hour = now.tm_hour % 12
    minute = now.tm_min
    second = now.tm_sec

    # Draw clock face
    canvas.create_oval(2, 2, WIDTH, HEIGHT, outline="black", width=2)

    # Draw hour numbers
    for i in range(12):
        angle = i * math.pi/6 - math.pi/2
        x = WIDTH/2 + 0.7 * WIDTH/2 * math.cos(angle)
        y = HEIGHT/2 + 0.7 * WIDTH/2 * math.sin(angle)
        if i == 0:
            canvas.create_text(x, y-10, text=str(i+12), font=("Helvetica", 12))
        else:
            canvas.create_text(x, y, text=str(i), font=("Helvetica", 12))
            
        
update_clock()
root.mainloop()
draw-hour-numbers-in-tkinter-analog-clock

Here in the above code:

  • line 24: Start a for loop to draw hour numbers on the clock face canvas. The loop runs 12 times, one for each hour
  • line 25: This line is used to calculate the angle of each hour number from 12 o’clock. This line of code makes sure that 12 o’clock is at the top, where:
    • i is the hour number
    • math.pi/6 term used because there are 12 hours numbers in total and we know the radians of a circle is 2 * math.pi. So each hour number is spaced 2 * math.pi / 12 = math.pi/6 radians apart. So in short math.pi/6 represents 1/12 of a circle or 30 degrees
    • math.pi/2 represents 90 degrees or 1/4 of a circle. The 12 o’clock position in an analog clock is at the top of the clock instead of the right. math.pi/2 is subtracted from angle to rotate the entire clock face 90 degrees counterclockwise. This is to ensure that the clock hands are drawn starting from the 12 o’clock position, rather than the 3 o’clock (0 degrees) position.
  • line 26-27: These lines calculate the x and y coordinates of the hour number on the clock canvas.
    • Here WIDTH/2 and HEIGHT/2 represent the center of the analog clock face
    • 0.7 * WIDTH/2 is used to reduce the radius of the clock face a little bit
    • math.cos(angle) and math.sin(angle) gives the cosine and sine values of the angle at which the number needs to be placed.
  • line 28-31: This line is used to finally draw the numbers in the clock canvas by creating text. We are starting from 12 o clock, this is the reason for using the if statement

2.3 Draw minute lines

In this section, we will draw minute line markers in our Tkinter analog clock. Below is the updated code to do that.

import tkinter as tk
import time
import math

WIDTH = 400
HEIGHT = 400

root = tk.Tk()
root.title("Analog Clock")
canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="white")
canvas.pack()

def update_clock():
    canvas.delete("all")
    now = time.localtime()
    hour = now.tm_hour % 12
    minute = now.tm_min
    second = now.tm_sec

    # Draw clock face
    canvas.create_oval(2, 2, WIDTH, HEIGHT, outline="black", width=2)

    # Draw hour numbers
    for i in range(12):
        angle = i * math.pi/6 - math.pi/2
        x = WIDTH/2 + 0.7 * WIDTH/2 * math.cos(angle)
        y = HEIGHT/2 + 0.7 * WIDTH/2 * math.sin(angle)
        if i == 0:
            canvas.create_text(x, y-10, text=str(i+12), font=("Helvetica", 12))
        else:
            canvas.create_text(x, y, text=str(i), font=("Helvetica", 12))

    # Draw minute lines
    for i in range(60):
        angle = i * math.pi/30 - math.pi/2
        x1 = WIDTH/2 + 0.8 * WIDTH/2 * math.cos(angle)
        y1 = HEIGHT/2 + 0.8 * HEIGHT/2 * math.sin(angle)
        x2 = WIDTH/2 + 0.9 * WIDTH/2 * math.cos(angle)
        y2 = HEIGHT/2 + 0.9 * HEIGHT/2 * math.sin(angle)
        if i % 5 == 0:
            canvas.create_line(x1, y1, x2, y2, fill="black", width=3)
        else:
            canvas.create_line(x1, y1, x2, y2, fill="black", width=1)
            
        
update_clock()
root.mainloop()
draw-minute-lines-in-python-tkinter-canvas-analog-clock

Here in this code, I guess I no need to explain the basic part like how to calculate the x and y-axis or how to calculate the angle, etc.

Also Read:  Deploy Object detection model using Flask

To draw a line we need a starting point and an endpoint. This is the reason we are defining x1, y1, x2 and y2 in our code.

Line 40-43 is to crate or draw minute lines in our clock canvas. We are making the minute line a little bit bolder every 5 minutes using if i % 5 == 0.

2.4 Draw clock hands

Finally, we will draw the hands of our analog clock which are the hour hand, minute hand, and second hand.

Below code is the final code to make Analog clock in python and Tkinter:

import tkinter as tk
import time
import math

WIDTH = 400
HEIGHT = 400

root = tk.Tk()
root.title("Analog Clock")
canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, bg="white")
canvas.pack()

def update_clock():
    canvas.delete("all")
    now = time.localtime()
    hour = now.tm_hour % 12
    minute = now.tm_min
    second = now.tm_sec

    # Draw clock face
    canvas.create_oval(2, 2, WIDTH, HEIGHT, outline="black", width=2)

    # Draw hour numbers
    for i in range(12):
        angle = i * math.pi/6 - math.pi/2
        x = WIDTH/2 + 0.7 * WIDTH/2 * math.cos(angle)
        y = HEIGHT/2 + 0.7 * WIDTH/2 * math.sin(angle)
        if i == 0:
            canvas.create_text(x, y-10, text=str(i+12), font=("Helvetica", 12))
        else:
            canvas.create_text(x, y, text=str(i), font=("Helvetica", 12))

    # Draw minute lines
    for i in range(60):
        angle = i * math.pi/30 - math.pi/2
        x1 = WIDTH/2 + 0.8 * WIDTH/2 * math.cos(angle)
        y1 = HEIGHT/2 + 0.8 * HEIGHT/2 * math.sin(angle)
        x2 = WIDTH/2 + 0.9 * WIDTH/2 * math.cos(angle)
        y2 = HEIGHT/2 + 0.9 * HEIGHT/2 * math.sin(angle)
        if i % 5 == 0:
            canvas.create_line(x1, y1, x2, y2, fill="black", width=3)
        else:
            canvas.create_line(x1, y1, x2, y2, fill="black", width=1)

    # Draw hour hand
    hour_angle = (hour + minute/60) * math.pi/6 - math.pi/2
    hour_x = WIDTH/2 + 0.5 * WIDTH/2 * math.cos(hour_angle)
    hour_y = HEIGHT/2 + 0.5 * HEIGHT/2 * math.sin(hour_angle)
    canvas.create_line(WIDTH/2, HEIGHT/2, hour_x, hour_y, fill="black", width=6)

    # Draw minute hand
    minute_angle = (minute + second/60) * math.pi/30 - math.pi/2
    minute_x = WIDTH/2 + 0.7 * WIDTH/2 * math.cos(minute_angle)
    minute_y = HEIGHT/2 + 0.7 * HEIGHT/2 * math.sin(minute_angle)
    canvas.create_line(WIDTH/2, HEIGHT/2, minute_x, minute_y, fill="black", width=4)

    # Draw second hand
    second_angle = second * math.pi/30 - math.pi/2
    second_x = WIDTH/2 + 0.6 * WIDTH/2 * math.cos(second_angle)
    second_y = HEIGHT/2 + 0.6 * WIDTH/2 * math.sin(second_angle)
    canvas.create_line(WIDTH/2, HEIGHT/2, second_x, second_y, fill="red", width=2)

    canvas.after(1000, update_clock)

update_clock()
root.mainloop()
Analog clock in python and Tkinter

Here in the above code:

  • Line 45-49: Drawing hour hand in the clock canvas
  • Line 51-55: Drawing minute hand
  • Line 57-61: Creating second hand in our clock canvas
  • Line 63: Refreshing clock drawing or re-calling update_clock function in each second (1000 milliseconds)
Also Read:  Upload and display image in Flask Python

Conclusion and Next Steps

In this Python project, we developed an analog and digital clock application using the Tkinter module of Python. In the first part of this tutorial, we created a digital clock app to display the time in digital format. Note that this example digital clock is showing time in 24-hour format. You can take it to next level to show time in a 12-hour format by adding one label to show AM or PM.

In the second part of the tutorial, you learned how to make an analog clock using Tkinter and Python. The basic concept to make an analog clock is to draw the analog clock GUI in the Tkinter canvas and change the drawing each second. This is the kind of clock animation you can assume.

You can implement this clock in your project by taking it to the next level by modifying the code to add new features to the analog clock, such as changing the color or style of the clock’s hands and face, adding an alarm or timer, etc.

This is it for this tutorial. If you have any questions or suggestions regarding this post, don’t hesitate to mention those in the comment section below.

Similar Read:

2 thoughts on “Build Digital & Analog Clock GUI with Python Tkinter”

  1. Thank you so much Anindya. This is a wonderfully clear presentation that an old Fortran programmer, but beginner to Python coding, could very easily follow. The only thing that confused me for a moment was that the y-coordinate seemed to have the wrong sign. Then I realized that (0,0) was the top left of the window and not the bottom left, so the y-direction is inverted from what I’m used to. Very best wishes to you.

    Reply

Leave a comment