One of the useful apps I've built recently is a simple floating clock for the desktop. This project allowed me to experiment with creating graphical user interfaces (GUIs) in Python using the Tkinter module. It also integrates additional functionality like setting alarms and changing colors.
The clock displays the current time in a large font centered on the screen. It automatically updates every second using Tkinter's after method to schedule regular updates. To make the window float above other apps, I used overrideredirect andwm_attributes to remove window decorations and set transparency.
A key feature is the ability to set an alarm. Users can choose the hour, minute and second for the alarm using dropdown menus. When the alarm time is reached, it plays an MP3 file selected from the filesystem using PyGame. This allows customizing the alarm sound.
import tkinter as tk
from tkinter import filedialog, colorchooser
from pygame import mixer
from datetime import datetime
- import tkinter as tk: This line imports the Tkinter library and aliases it as tk. Tkinter is a standard GUI (Graphical User Interface) toolkit for Python, providing a set of tools to create windows, widgets, and handle user events.
- from tkinter import filedialog, colorchooser: This line imports specific modules from Tkinter, namely filedialog and colorchooser. These modules provide functionalities for opening file dialogs to select files and choosing colors in the GUI, respectively.
- from pygame import mixer: This line imports the mixer module from the Pygame library. Pygame is a set of Python modules designed for writing video games, but the mixer module can be used for handling audio functionalities, such as playing music or sounds.
- from datetime import datetime: This line imports the datetime module, which provides classes for working with dates and times. In the context of this code snippet, datetime is likely to be used for timestamping or handling time-related operations in the application.
def center_window(root):
# Gets the requested values of the height and width.
windowWidth = root.winfo_reqwidth()
windowHeight = root.winfo_reqheight()
# Gets both half the screen width/height and window width/height
positionRight = int(root.winfo_screenwidth() / 2 - windowWidth / 2)
positionDown = int(root.winfo_screenheight() / 2 - windowHeight / 2)
# Positions the window in the center of the page.
root.geometry("+{}+{}".format(positionRight, positionDown))
root.overrideredirect(True)
root.geometry("400x200")
root.configure(bg='black')
root.attributes("-alpha", 0.9)
- This function centers the tkinter root window on the screen. It takes the root window as a parameter.
- It first uses winfo_reqwidth() and winfo_reqheight() to get the requested/preferred width and height of the window.
- It then calculates the horizontal and vertical position on the screen needed to center the window.
- It gets half the screen width/height and subtracts half the window width/height to position it in the center.
- The positionRight and positionDown variables contain the x and y coordinate for centering.
- It then calls root.geometry() to set the window size and position on screen using these coordinates.
# Add a rounded border to the window
root.wm_attributes('-transparentcolor', root['bg'])
root.wm_attributes('-alpha', 0.9)
root.attributes("-transparent", "blue")
root.attributes('-alpha', 0.9)
root.wait_visibility(root)
root.wm_attributes('-alpha', 1.0)
root.update_idletasks()
root.wm_attributes('-alpha', 0.9)
root.update_idletasks()
root.overrideredirect(False)
def update_clock():
global alarm_time
current_time = datetime.now().strftime('%H:%M:%S')
clock_label.config(text=current_time)
if alarm_time and current_time == alarm_time:
mixer.music.load(song_file)
mixer.music.play()
root.after(1000, update_clock)
- It gets the current date and time from the datetime module and formats it as HH:MM:SS.
- The current time string is set as the text of the clock_label widget to display on the GUI.
- A global alarm_time variable is used to check if an alarm is set.
- It compares the current_time to alarm_time. If they are equal, it means the alarm time is reached.
- When the alarm triggers, it loads the song_file selected by the user using PyGame mixer.
- The song is then played to trigger the alarm sound.
- The root.after() method schedules the update_clock() function to run again after 1000 milliseconds (1 second).
- This creates a recurring timer that updates the display clock and checks for alarms continuously.
def set_alarm():
global alarm_time
global song_file
alarm_time = f"{alarm_hour_var.get()}:{alarm_minute_var.get()}:{alarm_second_var.get()}"
song_file = filedialog.askopenfilename()
mixer.init()
mixer.music.load(song_file)
- global alarm_time: This variable holds the user-specified alarm time in the format "hour:minute:second". It is constructed using the values obtained from associated Tkinter variables (alarm_hour_var, alarm_minute_var, and alarm_second_var) representing the chosen hour, minute, and second.
- global song_file: This variable stores the path of the selected music file, which is obtained through a file dialog using filedialog.askopenfilename().
- mixer.init(): This initializes the Pygame mixer module, preparing it for handling audio operations.
- mixer.music.load(song_file): This loads the selected music file into the mixer, making it ready for playback when the alarm triggers.
root = tk.Tk()
root.title('Clock')
center_window(root)
clock_label = tk.Label(root, font=('calibri', 40), background='black', foreground='white')
clock_label.pack(pady=20)
alarm_hour_var = tk.StringVar(root)
alarm_hour_var.set('00')
alarm_minute_var = tk.StringVar(root)
alarm_minute_var.set('00')
alarm_second_var = tk.StringVar(root)
alarm_second_var.set('00')
alarm_time_label = tk.Label(root, text='Alarm Time:', background='black', foreground='white')
alarm_time_label.pack()
alarm_hour_menu = tk.OptionMenu(root, alarm_hour_var, *[f'{h:02}' for h in range(25)])
alarm_hour_menu.pack(side='left')
tk.Label(root, text=':', background='black', foreground='white').pack(side='left')
alarm_minute_menu = tk.OptionMenu(root, alarm_minute_var, *[f'{m:02}' for m in range(60)])
alarm_minute_menu.pack(side='left')
tk.Label(root, text=':', background='black', foreground='white').pack(side='left')
alarm_second_menu = tk.OptionMenu(root, alarm_second_var, *[f'{s:02}' for s in range(60)])
alarm_second_menu.pack(side='left')
set_alarm_button = tk.Button(root, text='Set Alarm', command=set_alarm)
set_alarm_button.pack()
change_color_button = tk.Button(root, text='Change Color', command=change_color)
change_color_button.pack()
- root = tk.Tk(): Initializes the main window for the application.
- root.title('Clock'): Sets the title of the application window to "Clock".
- center_window(root): Calls a function (center_window) to center the application window on the screen.
- clock_label = tk.Label(root, font=('calibri', 40), background='black', foreground='white'): Creates a label widget for displaying the clock. It is configured with a specific font, black background, and white foreground color.
- clock_label.pack(pady=20): Places and packs the clock label within the window with some padding.
- Three StringVar variables (alarm_hour_var, alarm_minute_var, alarm_second_var) are created to store the user-selected hour, minute, and second for setting the alarm.
- alarm_hour_menu, alarm_minute_menu, and alarm_second_menu are OptionMenu widgets providing drop-down menus for selecting the alarm time components.
- set_alarm_button: A button labeled "Set Alarm" is created. When clicked, it invokes the set_alarm function (not provided in the code snippet).
- change_color_button: Another button labeled "Change Color" is created. When clicked, it invokes the change_color function (not provided in the code snippet).
0 Comments