1
+ import tkinter as tk
2
+ from tkinter import ttk
3
+ from datetime import datetime
4
+ import pygame
5
+
6
+ #Initializing our audio mixer and setting the wav alarm file we want it to play when the alarm goes off
7
+ pygame .mixer .init (42050 , - 16 , 2 , 2048 )
8
+ alarm_sound = pygame .mixer .Sound ("MyAlarm.wav" )
9
+ #Setting our initial global values
10
+ start_printed = False
11
+ stop_printed = True
12
+ done = False
13
+ finished = False
14
+ stop_clicked = False
15
+
16
+ class AlarmApp (tk .Tk ):
17
+ def __init__ (self ):
18
+ tk .Tk .__init__ (self )
19
+ #Title of the window set to 'Alarm Clock'
20
+
21
+ self .title ("Alarm Clock" )
22
+ #Make it so user can't resize page
23
+ self .resizable (width = False , height = False )
24
+ #Set up all of the drop-down lists
25
+ self .hr = tk .IntVar (self )
26
+ self .min = tk .IntVar (self )
27
+ self .ampm = tk .StringVar (self )
28
+ #Set the initial values of each drop-down list
29
+ self .hr .set ('12' )
30
+ self .min .set ("00" )
31
+ self .ampm .set ("AM" )
32
+ #Create the list of values from which we are choosing from in our drop-down list
33
+ hours = []
34
+ minutes = []
35
+ ampmlist = ["AM" ,"PM" ]
36
+ #Hours go from 1 to 12
37
+ for x in range (1 ,13 ):
38
+ hours .append (x )
39
+ #Minutes go from 0 to 59
40
+ for y in range (0 ,60 ):
41
+ minutes .append ("%02d" % (y ,))
42
+ #Placing all of our list into the respective drop-down list
43
+ self .popmenuhours = tk .OptionMenu (self ,self .hr , * hours )
44
+ self .popmenuminutes = tk .OptionMenu (self ,self .min , * minutes )
45
+ self .popmenuAMPM = tk .OptionMenu (self , self .ampm , * ampmlist )
46
+ #Placing our drop-down lists on the page as well as one label
47
+ self .popmenuhours .pack (side = "left" )
48
+ self .thing = tk .Label (text = ":" ).pack (side = "left" )
49
+ self .popmenuminutes .pack (side = "left" )
50
+ self .popmenuAMPM .pack (side = "left" )
51
+ #Setting up all the buttons on the right hand side of the window. The text refers to what the button says
52
+ #Command refers to which function it will run once it's clicked
53
+ #State refers to whether it is clickable or not at the current state.
54
+ self .alarmbutton = tk .Button (self , text = "Set Alarm" , command = self .start_clock )
55
+ #I disabled both of these buttons since they should only be able to be pressed when it is appropriate and the alarm is running
56
+ self .cancelbutton = tk .Button (self , text = "Cancel Alarm" , command = self .stop_clock , state = "disabled" )
57
+ self .stopalarmbutton = tk .Button (self , text = "Stop Alarm" , command = self .stop_audio , state = "disabled" )
58
+ #Packing all the buttons into the page
59
+ self .alarmbutton .pack ()
60
+ self .cancelbutton .pack ()
61
+ self .stopalarmbutton .pack ()
62
+
63
+ def start_clock (self ):
64
+
65
+ global done , start_printed , stop_printed , stop_clicked
66
+ #Done refers to whether either the time has been reached or if the user has cancelled. I.e: Loop is done.
67
+ if done == False :
68
+ #Cancel button is now active so user can decide at any point to cancel the alarm
69
+ self .cancelbutton .config (state = "active" )
70
+ #Alarm button is now disabled since an alarm has currently already been set
71
+ self .alarmbutton .config (state = "disabled" )
72
+ #On the first run of the loop, let the user know that an alarm has been set for their desired time
73
+ if start_printed == False :
74
+ #Print this notification for the user in the terminal
75
+ print ("Alarm set for {}:{}{}" .format (self .hr .get (), "%02d" % (self .min .get ()),self .ampm .get ()))
76
+ #Now set this to true, since we have printed it, so that it doesn't print it again on every loop for this set alarm
77
+ start_printed = True
78
+ #Stop printed set to false so that once the user cancels the timer, it will print a message (As we'll see later in the code)
79
+ stop_printed = False
80
+ #These next two if-statements are converting our hours from our drop-down list into 24-hour time, so that we can use it through DateTime
81
+ if self .ampm .get () == "AM" :
82
+ if self .hr .get () in range (1 ,12 ):
83
+ hour_value = self .hr .get ()
84
+ else :
85
+ hour_value = self .hr .get () - 12
86
+ if self .ampm .get () == "PM" :
87
+ if self .hr .get () in range (1 ,12 ):
88
+ hour_value = self .hr .get () + 12
89
+ else :
90
+ hour_value = self .hr .get ()
91
+ #Now we call the Alarm function with the information that the user has entered to check whether we have reached the alarm time
92
+ self .Alarm ("%02d" % (hour_value ,), "%02d" % (self .min .get ()))
93
+ #If user has clicked the cancel alarm button, we reset everything
94
+ if stop_clicked == True :
95
+ done = False
96
+ start_printed = False
97
+ stop_clicked = False
98
+
99
+ def stop_clock (self ):
100
+ global done , stop_clicked
101
+ #Let the user know that the alarm has been cancelled by printing it in the terminal
102
+ print ("Alarm set for {}:{}{} has been cancelled" .format (self .hr .get (), "%02d" % (self .min .get ()),self .ampm .get ()))
103
+ #Cancel button has now been clicked
104
+ stop_clicked = True
105
+ #Now done with the current alarm/loop
106
+ done = True
107
+ #Buttons reset to what they were originally
108
+ self .cancelbutton .config (state = "disabled" )
109
+ self .alarmbutton .config (state = "active" )
110
+
111
+ def stop_audio (self ):
112
+ #Use PyGame to stop the audio since button has been clicked
113
+ pygame .mixer .Sound .stop (alarm_sound )
114
+ #Stop alarm button disabled and alarm button active, essentially reseting everything
115
+ self .stopalarmbutton .config (state = "disabled" )
116
+ self .alarmbutton .config (state = "active" )
117
+
118
+
119
+
120
+ def Alarm (self ,myhour ,myminute ):
121
+ global done , start_printed , finished
122
+ #If we are still not done, we follow this statement
123
+ if done == False :
124
+ #We convert the information into strings (To match DateTime)
125
+ myhour ,myminute = str (myhour ),str (myminute )
126
+ #Next, we extract the data of the current time from DateTime and take the information we want (hour and minute)
127
+ a = str (datetime .now ())
128
+ b = a .split (" " )[1 ].split (":" )
129
+ hour = b [0 ]
130
+ minute = b [1 ]
131
+ #Now, if the alarm time matches the current time, we follow his statement. Alarm is going to go off!
132
+ if hour == myhour and minute == myminute :
133
+ #Using pygame to play audio, loops = -1 refers to an infinite loop
134
+ pygame .mixer .Sound .play (alarm_sound , loops = - 1 )
135
+ print ("Alarm is ringing!" )
136
+ #We are now done
137
+ done = True
138
+ #Also finished
139
+ finished = True
140
+ #Now we change back the state of the cancel button to disabled, and the state of the alarm stop to active
141
+ #This is so the user can stop the alarm, since it will infinitely loop
142
+ self .cancelbutton .config (state = "disabled" )
143
+ self .stopalarmbutton .config (state = "active" )
144
+
145
+ else :
146
+ #If it is still not the set time, we recursively loop back to the start_clock function
147
+ self .after (1000 , self .start_clock )
148
+ done = False
149
+ #If we are finished, which we are when the alarm goes off, we reset everything
150
+ if finished == True :
151
+ start_printed = False
152
+ finished = False
153
+
154
+ app = AlarmApp ()
155
+ app .mainloop ()
0 commit comments