DEV Community

Cover image for How to Build a GUI Clock with Python: A Comprehensive Step-by-Step Guide
Scofield Idehen
Scofield Idehen

Posted on • Originally published at blog.learnhub.africa

How to Build a GUI Clock with Python: A Comprehensive Step-by-Step Guide

In the world of programming, creating a graphical user interface (GUI) clock is an excellent project for beginners and intermediate Python developers alike. This tutorial will guide you through building a customizable GUI clock using Python and the Tkinter library.

By the end of this article, you'll have a fully functional digital clock application and the skills to expand it further.

Setting Up Your Python Environment

Before we dive into coding our GUI clock, let's ensure your development environment is properly set up:

Installing Python

Download and install Python from the official website if you haven't already. During installation, check the box that says "Add Python to PATH" to run Python from the command line easily.
.

  • Verifying the Installation

Open your command prompt or terminal and type:

python --version
Enter fullscreen mode Exit fullscreen mode

This should display the installed Python version.

  • Tkinter Check

Tkinter comes pre-installed with most Python distributions. To verify, run Python in interactive mode and try importing Tkinter:

import tkinter
Enter fullscreen mode Exit fullscreen mode

If no error occurs, you're ready to proceed.

Understanding the Basic Concepts

Before we start coding, let's briefly cover some key concepts:

  • Tkinter

Tkinter is Python's standard GUI (Graphical User Interface) package. It provides a fast and easy way to create GUI applications.

  • Widgets

In Tkinter, everything is a widget. Buttons, labels, and frames are all examples of widgets. We'll primarily use the Label widget to display our clock.

  • The Event Loop:

GUI programs use an event-driven programming model. The program waits for events (like a button click) and responds to them. The main event loop manages this.

Building the Basic Clock

Let's start by creating a basic digital clock:

  • Import Required Modules:

Create a new Python file (e.g., gui_clock.py) and add the following imports:

import tkinter as tk
from time import strftime
Enter fullscreen mode Exit fullscreen mode

  • Create the Main Window:

Set up the main application window


    window = tk.Tk()
    window.title("Scofield GUI Clock")
    window.geometry("350x100")
Enter fullscreen mode Exit fullscreen mode

Let's break down these three lines of code:
window = tk.Tk() This line creates the main window for your graphical user interface (GUI) application.

tk.Tk() is a constructor that initializes a new top-level widget of Tkinter, which serves as the application's main window.

We assign this window object to the variable window, which we'll use to interact with and modify the window throughout our program.

window.title("Scofield GUI Clock")` 
Enter fullscreen mode Exit fullscreen mode

This line sets the title of the window.

  • The title() method is called on our window object.
  • It takes a string argument, which becomes the text displayed in the window's title bar.

In this case, the window's title will be "Scofield GUI Clock".

window.geometry("350x100")` 
Enter fullscreen mode Exit fullscreen mode

This line sets the initial size of the window.

  • The geometry() method is used to set the window's dimensions.
  • The argument "350x100" is a string specifying pixels' width and height.
  • This means the window will be 350 pixels wide and 100 pixels tall when it first appears.

Together, these lines do the following:

  • Create a new window for your application.
  • Set its title to "Scofield GUI Clock"
  • Set its initial size to 350 pixels wide by 100 pixels tall.

If you click on the play button at the top right of your screen, you won't see anything—just an empty space. Although your screen might look like something is there, you won't see anything.

Add the following line to your code and click play again, make sure to keep space inbetween so as we are going to add some lines of codes inbeween.

    window.mainloop()
Enter fullscreen mode Exit fullscreen mode

The window.mainloop() line is crucial in a Tkinter application. Here's what it does:

  • Starts the event loop:
  • It initiates the Tkinter event loop, a central part of any GUI application.
  • This loop continuously checks for and handles events (like mouse clicks or key presses).
  • Keeps the window open:

Without this line, the program would create the window and immediately exit.
mainloop() keeps the window displayed and the application running.

  • Define the Clock Function:

Create a function to update and display the time:


    def update_time():
        string = strftime('%H:%M:%S %p')
        label.config(text=string)
        label.after(1000, update_time)
Enter fullscreen mode Exit fullscreen mode

Lets break down the code above

def update_time():
Enter fullscreen mode Exit fullscreen mode

This line defines a new function named update_time.
This function will be responsible for updating the clock display.

string = strftime('%H:%M:%S %p')
Enter fullscreen mode Exit fullscreen mode

strftime() is a function from the time module that formats the current time.

'%H:%M:%S %p' is the format string:
%H: Hour (24-hour clock) as a decimal number [00,23]
%M: Minute as a decimal number [00,59]
%S: Second as a decimal number [00,59]
%p: Locale's equivalent of either AM or PM
Enter fullscreen mode Exit fullscreen mode

This creates a string with the current time in the format "HH:MM:SS AM/PM"

label.config(text=string)
Enter fullscreen mode Exit fullscreen mode

This updates the text of the label widget (which we assume was created earlier in the code).
It sets the label's text to the time string we just created.

    label.after(1000, update_time)
    after() is a method that schedules a function to be called after a certain delay.
    1000 is the delay in milliseconds (1 second).
    update_time is the function to be called after the delay.
Enter fullscreen mode Exit fullscreen mode

This line essentially says "call the update_time function again after 1 second".
The function does the following:

  • Gets the current time and formats it into a string.
  • Updates the label with this time string.
  • Schedules itself to run again after 1 second.
  • Create and Style the Label:

Add a label to display the time and style it:

    label = tk.Label(window, font=('calibri', 40, 'bold'), background='black', foreground='white')
    label.pack(anchor='center')

Enter fullscreen mode Exit fullscreen mode
  • Start the Clock and Run the Main Loop:

Initiate the clock update and start the main event loop

    update_time()
    window.mainloop()
Enter fullscreen mode Exit fullscreen mode

Enhancing the Clock

Now that we have a basic clock let's add some features to make it more interesting and user-friendly.

We have created our clock at this point, but having just one is not enough. Let’s work on enhancing the clock and adding more functionality.

  • Add Date Display:

Modify the update_time() function to include the date, and replace the code on your editor with the one below.

    def update_time():
        time_string = strftime('%H:%M:%S %p')
        date_string = strftime('%B %d, %Y')
        time_label.config(text=time_string)
        date_label.config(text=date_string)
        time_label.after(1000, update_time)

    time_label = tk.Label(window, font=('calibri', 40, 'bold'), background='black', foreground='white')
    time_label.pack(anchor='center')

    date_label = tk.Label(window, font=('calibri', 24), background='black', foreground='white')
    date_label.pack(anchor='center')
Enter fullscreen mode Exit fullscreen mode

Let us review what we did.

New date functionality: date_string = strftime('%B %d, %Y')

This line creates a new string with the current date.

    %B: Full month name
    %d: Day of the month
    %Y: Year with century
Enter fullscreen mode Exit fullscreen mode

Separate labels for time and date:
Instead of a single label, we now have two: time_label and date_label.

    time_label.config(text=time_string)
    date_label.config(text=date_string)

Enter fullscreen mode Exit fullscreen mode
  • These lines update the text of each label separately.
  • Updated scheduling: time_label.after(1000, update_time)
  • The scheduling is now done on the time_label instead of a generic label.
  • Creation of date_label:
    date_label = tk.Label(window, font=('calibri', 24), background='black', foreground='white')
    date_label.pack(anchor='center')

Enter fullscreen mode Exit fullscreen mode
  • This creates a new label specifically for the date.
  • It uses a smaller font size (24) than the time label (40).
  • It's also centered in the window.

These changes allow the clock to display both the current time and date, with the date appearing below the time in a slightly smaller font. The update function refreshes both pieces of information every second, providing a more comprehensive time display.
it should look like this below.

Add Color Customization

Let's allow users to change the background and text color

    def change_color():
        colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange']
        current_bg = time_label.cget("background")
        next_color = colors[(colors.index(current_bg) + 1) % len(colors)]
        time_label.config(background=next_color)
        date_label.config(background=next_color)

    color_button = tk.Button(window, text="Change Color", command=change_color)
    color_button.pack(anchor='center', pady=10)
Enter fullscreen mode Exit fullscreen mode

With the above explanation, we explored how labels work, so I won't explain that for color, but if you run this code, it won’t work.

What we would see is the button to change color, but when we click on it, the color will not change because we have yet to include the default color.

Add ‘black’ to the color list.

Add 12/24 Hour Format Toggle

Implement a feature to switch between 12-hour and 24-hour formats. Here is the code, but you will have to figure it out yourself and insert it into your line of code.

    is_24_hour = True

    def toggle_format():
        global is_24_hour
        is_24_hour = not is_24_hour

    def update_time():
        global is_24_hour
        time_format = '%H:%M:%S' if is_24_hour else '%I:%M:%S %p'
        time_string = strftime(time_format)
        date_string = strftime('%B %d, %Y')
        time_label.config(text=time_string)
        date_label.config(text=date_string)
        time_label.after(1000, update_time)

    format_button = tk.Button(window, text="Toggle 12/24 Hour", command=toggle_format)
    format_button.pack(anchor='center', pady=5)
Enter fullscreen mode Exit fullscreen mode

If you do it correctly, this is how your code will turn out at the end.

Final Code

Here's the complete code for our enhanced GUI clock:

    import tkinter as tk
    from time import strftime

    window = tk.Tk()
    window.title("Python GUI Clock")
    window.geometry("350x200")

    is_24_hour = True

    def update_time():
        global is_24_hour
        time_format = '%H:%M:%S' if is_24_hour else '%I:%M:%S %p'
        time_string = strftime(time_format)
        date_string = strftime('%B %d, %Y')
        time_label.config(text=time_string)
        date_label.config(text=date_string)
        time_label.after(1000, update_time)

    def change_color():
        colors = ['red', 'green', 'blue', 'yellow', 'purple', 'orange']
        current_bg = time_label.cget("background")
        next_color = colors[(colors.index(current_bg) + 1) % len(colors)]
        time_label.config(background=next_color)
        date_label.config(background=next_color)

    def toggle_format():
        global is_24_hour
        is_24_hour = not is_24_hour

    time_label = tk.Label(window, font=('calibri', 40, 'bold'), background='black', foreground='white')
    time_label.pack(anchor='center')

    date_label = tk.Label(window, font=('calibri', 24), background='black', foreground='white')
    date_label.pack(anchor='center')

    color_button = tk.Button(window, text="Change Color", command=change_color)
    color_button.pack(anchor='center', pady=10)

    format_button = tk.Button(window, text="Toggle 12/24 Hour", command=toggle_format)
    format_button.pack(anchor='center', pady=5)

    update_time()
    window.mainloop()
Enter fullscreen mode Exit fullscreen mode

Running and Testing Your Clock

Save the file and run it using Python.

To do this, save your file by clicking on the file and clicking on Save as.

Give your project a name, and save it with the .py at the end. Keep in mind where you are saving the file, as I am saving mine in Kivy; you can save yours in the document so you can easily navigate to it.

Open your terminal on Vscode or whatever editor and navigate to that folder or placed where you stored your file.

If it is in the Document use cd Document then run a ls to see if your file is there.

Once you see your folder, run a cd Kivy or if yours is a file, run.

python clock.py
Enter fullscreen mode Exit fullscreen mode

You should see a window appear with your digital clock displaying both time and date. To access the customization features, try clicking the "Change Color" and "Toggle 12/24 Hour" buttons.

If you have the play button we discussed at the beginning, you can click on it to see your work.

User-uploaded image: Screenshot+2024-06-20+at+16.48.09.png

If you want to take your coding to the next level, you can implement any of the following enhancements to aid your learning.

  • Add Alarm Functionality
  • Include Multiple Time Zones
  • Improve the GUI Layout
  • Add Themes: ## Conclusion

Congratulations! You've successfully created a customizable GUI clock using Python and Tkinter. This project has introduced you to key concepts in GUI programming, including widgets, event handling, and dynamic updates.

As you continue exploring Python and GUI development, you'll find that the skills you've learned form a solid foundation for more complex applications.

Remember, practice and experimentation are the best ways to improve your programming skills. Don't hesitate to modify the code, add new features, or start new projects based on your learning. Happy coding!

Libraries
Basic with Kivy
Python Spy cam

Top comments (0)