-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTimer.py
259 lines (236 loc) · 9.37 KB
/
Timer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# Import
from tkinter import Tk, Label, Button, Menu, Toplevel, Entry, Checkbutton, BooleanVar
from pyglet import font as pygletFont
import json, time, datetime, winsound
# create root
root = Tk()
# Load fonts
try:
pygletFont.add_file('fonts/digital-7.ttf')
except:
print('Error loading fonts')
# tkinter window class
class MyTimer:
def __init__(self, master):
# master
self.master = master
# variables
# counter used in timer
self.tiks = 0
# check if start has been pressed
self.pressed = False
# Init runonce variable
self.runonce = False
# timeout entry
self.var = BooleanVar()
# init var
self.var.set(False)
# Init after
self.AFTER = None
# width & height
w = 330
h = 200
# center screen
ws = self.master.winfo_screenwidth()
hs = self.master.winfo_screenheight()
x = (ws/2 - w/2)
y = (hs/3 - h/2)
# screen size
self.master.geometry('%dx%d+%d+%d' % (w,h,x,y))
# fixed size screen
self.master.resizable(0,0)
# screen title
self.master.title('Drink water bitch')
# screen color
self.master['bg'] = 'black'
# Create menu bar
menu_bar = Menu(self.master)
# Add menu to master
self.master.config(menu=menu_bar)
# Add command to menu bar
menu_bar.add_command(label='Configuration', command=self.TimerConfig)
# Timer Label
self.timer_label = Label(self.master, text='00:00', font=('digital-7',60),
fg='lawn green', bg='black')
# Pack Timer Label
self.timer_label.pack(pady=5)
# Clock Label
self.clock_label = Label(self.master, text='00:00:00', font=('digital-7',20),
fg='lawn green', bg='black')
# Pack Clock Label
self.clock_label.pack(pady=1)
# Start Button
self.btn_start = Button(self.master, text='Start', command=self.StartTimer,
height=2, width=10, fg='white', bg='black',
activeforeground='black', activebackgroun='black')
# Pack Start Button
self.btn_start.pack(side='left',padx=60)
# Stop Button
self.btn_stop = Button(self.master, text='Stop', command=self.StopTimer,
height=2, width=10, fg='red', bg='black',
activeforeground='black', activebackgroun='black')
# Pack Stop Button
self.btn_stop.pack(side='left')
# load settings
with open('conf/conf.json') as f:
self.conf_file = json.load(f)
self.timeout = self.conf_file['timer']
self.autostart = self.conf_file['autostart']
# start clock
self.clock()
# check if autostart is true
if self.autostart:
# start timer
self.StartTimer()
# functions
def TimerConfig(self):
'''timer configuration window'''
# create settings window
self.settingsWindow = self.CreateWindow(self.master,'black',(220,180),'Settings')
# Current time setting label
currTime_label = Label(self.settingsWindow, text=f'Current time settings {self.timeout}',
font=('digital-7',15), fg='lawn green', bg='black').pack(pady=5)
# Input label
timeout_label = Label(self.settingsWindow, text='Set timeout',
font=('digital-7',15), fg='lawn green', bg='black').pack(pady=1)
# Input for new time
setTime = Entry(self.settingsWindow, font=('digital-7',15), fg='red',
bg='black', insertbackground='white')
# pack setTime Entry
setTime.pack()
# auto start checkbox
btn_auto = Checkbutton(self.settingsWindow, text='Auto-Start', fg='white', bg='black',
activeforeground='black', variable=self.var, onvalue=True,
offvalue=False, activebackground='black', selectcolor='black')
# if autostart is true or false, mark or unmark checkbutton
if self.autostart:
btn_auto.select()
else:
btn_auto.deselect()
# pack btn_auto
btn_auto.pack()
# save settings button
btn_save = Button(self.settingsWindow, text='Save', font=('',10), fg='white', bg='black',
activeforeground='black', activebackground='black',
command=lambda:[self.save(setTime.get(),self.var.get()), self.closewindow(self.settingsWindow)])
# pack save button
btn_save.pack(pady=15)
def is_not_blank(self, s):
return bool(s and s.strip())
def save(self, t, auto):
try:
# check if time is not a blank space
if self.is_not_blank(t):
# if is not a blank space, convert to int and store time
self.int_t = int(t)
else:
# if blank space, use time in configuration file
self.int_t = self.timeout
except ValueError:
'''If input is not an integer, show error message'''
# create error message window
error_window = self.CreateWindow(self.settingsWindow, 'black',(200,50),'Error')
# add error label
error_lable = Label(error_window, text='Time must be an Integer', font=('digital-7',15),
fg='red', bg='black').pack(pady=5)
# save timer setting
self.conf_file['timer'] = self.int_t
# save autostart setting
self.conf_file['autostart'] = auto
# set new timeout
self.timeout = self.int_t
# save new settings in conf.json
with open('conf/conf.json','w') as json_conf_file:
json.dump(self.conf_file, json_conf_file)
def closewindow(self, window):
window.destroy()
def btnPressed(self):
'''change status that start btn has been pressed'''
self.pressed = True
def StopTimer(self):
'''Stops timer and reset variables'''
# stop alarm
self.stopAlarm()
# reset runonce variable
self.runonce = False
# reset tiks counter
self.tiks = 0
# reset timer label
self.timer_label['font'] = ('digital-7', 60)
self.timer_label['text'] = '00:00'
self.timer_label['fg'] = 'lawn green'
# reset pressed
self.pressed = False
# reset start button
self.btn_start['command'] = self.StartTimer
# stop after loop
if self.AFTER is not None:
# check if after has been called once
self.timer_label.after_cancel(self.AFTER)
def clock(self):
'''Gets current time and display it every second
in clock_label'''
# get current time
current_time = datetime.datetime.now()
now = current_time.strftime("%I:%M:%S")
# set time in label
self.clock_label['text'] = now
# # call clock function every 1 second
self.clock_label.after(1,self.clock)
def StartTimer(self):
''' Start timer and start alarm'''
# check if start button has already been pressed
if not self.pressed:
#if pressed, change command of button
self.btn_start['command'] = self.btnPressed
# increment counter
self.tiks += 1
# get minutes and seconds
minutes, seconds = divmod(self.tiks, 60)
time = '{:02d}:{:02d}'.format(minutes, seconds)
if minutes >= self.timeout:
'''check if timer is equal to timeout setting'''
if not self.runonce:
# Play Alarm once
self.playAlarm()
# change status of runonce
self.runonce = True
# change text in timer_label
self.timer_label['font'] = ('digital-7', 30)
self.timer_label['text'] = 'DRINK WATER, GET UP!!'
self.timer_label['fg'] = 'red'
else:
# set time in timer_label
self.timer_label['text'] = time
# create instance of after to stop it later and to loop function
self.AFTER = self.timer_label.after(1000, self.StartTimer)
def playAlarm(self):
'''play alarm'''
# Creo que no funciona con .mp3 y solo con .wav
winsound.PlaySound('audio/AlarmaDespiertaBasuraHumana.mp3', winsound.SND_FILENAME | winsound.SND_LOOP | winsound.SND_ASYNC)
def stopAlarm(self):
'''stop alarm'''
winsound.PlaySound(None, winsound.SND_PURGE)
def CreateWindow(self, ParentW, color, size, title):
'''Create a Toplevel object in case a new window is needed'''
new_window = Toplevel(ParentW)
# new window size
w,h = size
# center new window
ws = self.master.winfo_screenwidth()
hs = self.master.winfo_screenheight()
x = (ws/2 - w/2)
y = (hs/3 - h/2)
# new window size
new_window.geometry('%dx%d+%d+%d' % (w,h,x,y))
# new window fixed screen
new_window.resizable(0,0)
# new window title
new_window.title(title)
# new window color
new_window['bg'] = color
return new_window
# Timer Object
Gui = MyTimer(root)
# Run loop
root.mainloop()