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
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
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
- Create the Main Window:
Set up the main application window
window = tk.Tk()
window.title("Scofield GUI Clock")
window.geometry("350x100")
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")`
This line sets the title of the window.
- The
title()
method is called on ourwindow
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")`
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()
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)
Lets break down the code above
def update_time():
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')
s
trftime()
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
This creates a string with the current time in the format "HH:MM:SS AM/PM"
label.config(text=string)
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.
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')
- Start the Clock and Run the Main Loop:
Initiate the clock update and start the main event loop
update_time()
window.mainloop()
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')
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
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)
- 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')
- 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)
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)
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()
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
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.
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!
Top comments (0)