so I have a basic alarm python GUI, nothing fancy is still in need of a lot of work. So currently my code works as follow: The user clicks "create new alarm" and it opens a window with 3 option menu widgets and selected the time he wants the alarm to go off, then once the set alarm is clicked a loop is run that counts down at one second every time the loop is repeated and the time is printed in the console than when the time they set is equal to the current time the alarm goes off.
Now my problem is that I want that countdown that is in the console to be displayed on the GUI. I tried to simply make a label and use .get to fetch the current value and display them but once the loop starts it won't do any other code. If I have any other suggestions I am all ears. All i want is a countdown that shows how much time till the alarm goes off, my current idea in my trial and error plan is to display the console.
Here is my code:
# Import Required Library
from tkinter import *
import datetime
import time
import winsound
from threading import *
from tkinter import messagebox
def submit():
def alarm(Curent):
# Infinite Loop
while True:
# Set Alarm
set_alarm_time = f"{hour.get()}:{minute.get()}:{second.get()}"
# Wait for one seconds
time.sleep(1)
# Get current time
current_time = datetime.datetime.now().strftime("%H:%M:%S")
print(current_time,set_alarm_time)
Curent = current_time
set = set_alarm_time
# Check whether set alarm is equal to current time or not
if current_time == set_alarm_time:
print("Time to Wake up")
# Playing sound
winsound.PlaySound("sound.wav",winsound.SND_ASYNC)
messagebox.showinfo(title="ALARM", message="Alarm is going off, its time to wake up!")
break
root = Tk()
root.geometry("400x300")
root.config(bg="#447c84")
root.title('MathAlarm')
# Add Labels, Frame, Button, Optionmenus
Label(root,text="Alarm Clock",font=("Helvetica 20 bold"),fg="Black").pack(pady=10)
Label(root,text="Set Time",font=("Helvetica 15 bold")).pack()
frame = Frame(root)
frame.pack()
hour = StringVar(root)
hours = ('00', '01', '02', '03', '04', '05', '06', '07',
'08', '09', '10', '11', '12', '13', '14', '15',
'16', '17', '18', '19', '20', '21', '22', '23', '24'
)
hour.set(hours[0])
hrs = OptionMenu(frame, hour, *hours)
hrs.pack(side=LEFT)
minute = StringVar(root)
minutes = ('00', '01', '02', '03', '04', '05', '06', '07',
'08', '09', '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')
minute.set(minutes[0])
mins = OptionMenu(frame, minute, *minutes)
mins.pack(side=LEFT)
second = StringVar(root)
seconds = ('00', '01', '02', '03', '04', '05', '06', '07',
'08', '09', '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')
second.set(seconds[0])
secs = OptionMenu(frame, second, *seconds)
secs.pack(side=LEFT)
Button(root,text="Set Alarm",font=("Helvetica 15"),command=alarm).pack(pady=20)
Button(root,text="Exit",font=("Helvetica 15"), command=lambda:root.destroy()).pack(pady=20)
root = Tk()
root.title('MathAlarm')
root.geometry('347x400')
root.config(bg="#447c84")
welcomelabel = Label(root, text="Welcome to Math Alarm", font=("Times", "24", "bold"))
welcomelabel.pack()
ext = Button(root, text="Exit", padx=20, pady=10, relief=SOLID, font=("Times", "14", "bold"), command=lambda:root.destroy())
reg = Button(root, text="Create new Alarm", padx=20, pady=10, relief=SOLID, font=("Times", "14", "bold"), command=submit)
ext.pack()
reg.pack()
# Execute Tkinter
root.mainloop()`
CodePudding user response:
Well I tried a different approach which does not uses the custom threading at all but uses tkinter's own main loop, it has it's own drawbacks and advantages too. I made following changes in your code to make it work
- Global variables for hours, mins and seconds
- Global variable for the output label
- Separated your alarm function from submit function
- Removed alarm function from button command
There is an option in the tkinter to run a function withing the main loop of tkinter periodically that way you won't be blocking any events processing of tkinter or any other process as tkinter itself take care of that check documentation of