Alarm Clock Program Python Pygame Customizable

by pinabanana in Circuits > Clocks

21 Views, 0 Favorites, 0 Comments

Alarm Clock Program Python Pygame Customizable

Screenshot 2025-11-18 102634.png

This is a clock made entirely with python it is built using some added python library moduls such as pygames it is a cool project if you are trying to learn some things on the passing of time in python

Supplies

-Computer

-Python IDE(I used VScode it is free)

-library python moduels(pygames timedate and sys)

Install Python

Screenshot 2025-11-18 103349.png

This step is optional if you already have Python installed or have it pre-installed on your computer. For installation, navigate to the official Python website and download the latest version. After the download, launch the installer and follow the steps provided on-screen. Once the installation completes, you may open PowerShell or Command Prompt and type python to check whether the process was successful. If everything is set up right, it would open the Python interpreter.

Installing Pygames, Datetime and Sys

You will need to install pygame, datetime, and sys to run this program.

First, open PowerShell or Command Prompt and type:


pip install pygame

(Do not run this inside the Pygame interpreter—use PowerShell or Command Prompt.)

If you typed it in correctly, it will install and a message will appear that Pygame was downloaded.


Next, to install datetime: if you have a recent version of Python, it should already be included. If not, go to PowerShell and type:


pip install DateTime

Make sure to use the capital letters.

For sys, like datetime, it comes installed with python. If for whatever reason you don’t have it, you can try:


pip install sys

That should be everything you need.

IDE

An IDE isn't the same thing as the interpreter; the IDE has an interpreter included in it, but it also comes with stuff like a text editor. When you install Python, you are installing the programming language itself-Python is just rules and syntax. The interpreter's job is to execute your code and check that the syntax is proper. One can use PowerShell or Command Prompt as their interpreter, but if one wants color-coding, file organization, and project tools, it is better to use a proper IDE.

Python does have its own IDE out of the box, but personally, I suggest that you use VS Code just because it makes managing projects much easier. If you already have a favorite IDE, then by all means continue to use it, otherwise consider your options. No IDE is inherently “better” than another—all IDEs will run Python according to the same rules. All the actual differences are in how they display your code, how they organize your files, and what extra tools they provide for you. Choosing an IDE is really a matter of personal preference.

Setting Everything Up

Screenshot 2025-11-18 105713.png

Let's start coding! The first step is to create a new file in your IDE or text editor. After you've created the file, the first step is to import all the libraries you installed. You import libraries in order to use that library in code. As an example of why you might want to import a library, when you call pygame.init(), this will initialize Pygame's internal modules, including the fonts and mixer system. This way you can be certain things like sounds and graphics are ready to be used and your program will not produce any errors related to text rendering mistakes.

=

Screenshot 2025-11-19 095646.png
Screenshot 2025-11-20 104125.png

1. time_wake – This is the time the alarm will go off. I use military time because it’s easier for the program to work with, even though the display will show 12-hour time later. Military time is just used internally.


2. audio - This is the sound file that will play when the alarm goes off. You can download any MP3 file and copy its file path. To make things easier, put the audio file in the same folder as your Python script so Python can find it easily. Make sure your path is in quotation marks, and add an r in front of the string (example: r"path\to\file.mp3") so Python doesn’t misread characters like

or \u.


Also remember to load this file into the Pygame mixer.


3. snooze_add: This is how many minutes the snooze button will add when pressed.


4. width and height - This dictates the window size. I made mine small so that it can stay in the background, but you can make it full screen if you want. Just remember that if you're going to make the window bigger you will have to scale up the text size, button size, and spacing so everything will still look nice.


5. screen – You don’t have to alter this. This just makes a window for the program with the width and height values set


6. font This is the font your program will use. You can choose anything—medieval, futuristic, or even a custom .ttf file. Just include the path to the font file (also with an r in front) and set the second number to the font size you want


7. stop and snooze images – These are the images for your stop and snooze buttons. I made mine in Microsoft Paint but you can use any images you find or create. 8. time_offset: This value determines how much time changes whenever the alarm is edited in edit mode, which we will create later on.

Button Class

Screenshot 2025-11-19 100328.png

The Button class defines what a button is and how it behaves. The first part of the class determines where the button is located on the screen. The second part defines how the button is pressed-if the mouse click falls within the area that the button is placed, then it's considered a button press by the program. The class also assists in tracking how long the button has been pressed.

Buttons

Screenshot 2025-11-19 102540.png

This section simply sets the position of the button and tells the program which image to use for that button.

If you want to scale your button image up or down, you can use:


stp_btn = pygame.transform.scale(stp_btn, (200, 300))

If you don’t know exactly how large the image should be, you can scale it relative to its original size like this:


stp_btn = pygame.transform.scale(
stp_btn,
(int(width_of_image * 1.2), int(height_of_image * 1.2))
)

The value 1.2 scales the image to 120% of its original size.

Make sure you apply the same scaling to both button images so they stay consistent.

Timer

Screenshot 2025-11-19 133241.png

Here we have some timer functions and formatting settings. This section simply defines a few things, including the time zone. The event with the value 1000 is used to track how much time has passed—basically, it triggers every 1000 milliseconds (1 second) so the program can update time-based events.

Stopping Audio

Screenshot 2025-11-19 133508.png

This section simply defines the action for stopping the audio. When you press the snooze or stop button, this function is what stops the sound from playing.

States

Screenshot 2025-11-19 140244.png

States are very important because they let the program know what it should be doing at any given moment. The running state controls whether the program is still active—so when you press the X button, the program knows to close. Without this, the program would keep running even after you tried to close the window.

Next, we have the edit modes. These states are used when you are adjusting the alarm time inside the program. Instead of closing the program and changing the code manually, you can enter an edit mode and change the time using buttons in the interface.

The flash states is the indicator that show when you’ve entered an edit mode, so you can clearly see that the value you are changing is active and being updated.

Time for the While Loop

Screenshot 2025-11-20 104530.png

Now we’re starting the main loop that uses everything we set up earlier. The first thing we do is start the loop using running = True, which we defined before. This tells the program: as long as running is true, keep looping and executing the code inside this section.

The next part gets the current system time, which becomes the variable now. This represents the time at the moment the program is running, as well as the time you can modify later through the edit mode.

The line that fills the screen with black simply redraws the background each frame. If you run the program at this point, you’ll just see a black window because nothing has been drawn on top of it yet.

Flash Seconds

Screenshot 2025-11-19 141442.png

Now we’re working on the flash timing. This tells Python when to make the text flash by temporarily hiding it. The program does this by replacing the text with an empty string for a certain amount of time, and then showing the text again for the same amount of time. The value 0.5 controls the length of the interval between each flash.

Edit Mode

Screenshot 2025-11-19 141624.png

The first section labeled edit mode clock is the edit mode for adjusting the current clock time. This shows exactly what I mentioned earlier: the program displays an empty string for a set amount of time to create the flashing effect. The same thing happens in edit mode alarm, which handles flashing while you are editing the alarm time.

Placement

Screenshot 2025-11-19 145623.png

This part of the code tells Python where to place your time text on the screen, allowing you to move it around and position it wherever works best for your layout.

Press

Screenshot 2025-11-19 145743.png

This section simply defines the names or variables used to track how long each button has been pressed.

Stop Button If Else

Screenshot 2025-11-20 104742.png

This section explains how the stop button works. It says that if the stop button is held for more than 1.5 seconds, the program should enter the time edit mode. It also controls what happens when you exit the edit modes—holding the stop button again for more than 1.5 seconds saves the changes and updates the time.

If the stop button is pressed while already in edit mode but held for less than 1.5 seconds, then it adjusts the hour value instead of switching modes.

The part labeled edit mode = alarm works the same way, but instead of editing the current clock time, it edits the alarm time.

Snooze Button If Else

Screenshot 2025-11-21 113830.png

This section works the same way as the stop button definition, but with a few differences. The snooze button activates the edit mode for the alarm instead of the clock. And rather than ending the alarm, pressing the snooze button adds time to the snooze duration.

Update

Screenshot 2025-11-20 111148.png

This how it updates and what happens during update. this also say what happens when the seconds the minutes and the hours line up. and the last bit is the display flip meaning it changes the entire display.

Final Code

Here is what the final code should look like:


import pygame
from datetime import datetime, timedelta
import sys

pygame.init()
pygame.mixer.init()

#setup
alarm_triggered = False
time_wake = "12:43:00"
pygame.mixer.music.load(r"C:\Users\natip\OneDrive\Desktop\Python\mixkit-rooster-crowing-in-the-morning-2462.mp3")

snooze_add = timedelta(minutes=5)

(width, height) = (225, 110)
screen = pygame.display.set_mode((width, height))
font = pygame.font.SysFont("Arial", 40)
text_color = (255, 255, 255)

stp_btn = pygame.image.load('stop_btn.png').convert_alpha()
snooze_btn = pygame.image.load('snooze_btn.png').convert_alpha()

time_offset = timedelta()

# button class
class Button:
def __init__(self, x, y, image):
self.image = image
self.rect = self.image.get_rect(topleft=(x, y))
self.held = False
self.hold_start = None

def draw(self):
screen.blit(self.image, (self.rect.x, self.rect.y))
pos = pygame.mouse.get_pos()
clicked = pygame.mouse.get_pressed()[0]

if self.rect.collidepoint(pos):
if clicked and not self.held:
self.held = True
self.hold_start = datetime.now()
elif not clicked and self.held:
duration = (datetime.now() - self.hold_start).total_seconds()
self.held = False
return duration
elif not clicked:
self.held = False

return None

# button
stp_button = Button(155, 25, stp_btn)
snooze_button = Button(20, 25, snooze_btn)

#timer
UPDATE_EVENT = pygame.USEREVENT + 1
pygame.time.set_timer(UPDATE_EVENT, 1000)

alarm_time_obj = datetime.strptime(time_wake, "%H:%M:%S")

#audio stop
def stop_sound_pygame():
pygame.mixer.music.stop()

#states
running = True
edit_mode = None
edit_start_time = None
edited_time = None
alarm_edit_time = None

flash_state = True
last_flash = datetime.now()

#clock start
while running:
now = datetime.now() + time_offset
screen.fill((0, 0, 0))

#flash
if (datetime.now() - last_flash).total_seconds() >= 0.5:
flash_state = not flash_state
last_flash = datetime.now()

#display of edit mode
if edit_mode == "clock":
if flash_state:
display_str = edited_time.strftime("%I:%M:%S %p")
else:
display_str = ""
elif edit_mode == "alarm":
if flash_state:
display_str = alarm_edit_time.strftime("%I:%M:%S %p")
else:
display_str = ""
else:
display_str = now.strftime("%I:%M:%S %p")

time_surface = font.render(display_str, True, text_color)
screen.blit(time_surface, (20, 50))

stp_duration = stp_button.draw()
snooze_duration = snooze_button.draw()

#stop button
if stp_duration:
if edit_mode == "clock":
if stp_duration > 1.5:
time_offset += (edited_time - datetime.now())
edit_mode = None
else:
edited_time += timedelta(hours=1)
elif edit_mode == "alarm":
if stp_duration > 1.5:
alarm_time_obj = alarm_edit_time
edit_mode = None
else:
alarm_edit_time += timedelta(hours=1)
else:
if stp_duration > 1.5:
edit_mode = "clock"
edited_time = now
else:
if alarm_triggered:
stop_sound_pygame()
alarm_triggered = False

#snooze button
if snooze_duration:
if edit_mode == "clock":
if snooze_duration <= 1.5:
edited_time += timedelta(minutes=1)
elif edit_mode == "alarm":
if snooze_duration > 1.5:
alarm_time_obj = alarm_edit_time
edit_mode = None
else:
alarm_edit_time += timedelta(minutes=1)
else:
if snooze_duration > 1.5:
edit_mode = "alarm"
alarm_edit_time = alarm_time_obj
else:
if alarm_triggered:
stop_sound_pygame()
alarm_time_obj += snooze_add
alarm_triggered = False

# update
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False

if event.type == UPDATE_EVENT:
if not edit_mode:
current_time_obj = now.time()

if (current_time_obj.hour == alarm_time_obj.hour and
current_time_obj.minute == alarm_time_obj.minute and
current_time_obj.second == alarm_time_obj.second and
not alarm_triggered):

pygame.mixer.music.play(-1)
alarm_triggered = True

pygame.display.flip()




Downloads