0

I have developed a code that allows me do set an alarm clock which can play sound effect:

import time
import tkinter as tk
import playsound

window = tk.Tk()
window.title('Alarm clock')

#where the problem lies
def submit():
    hr=int(txtHr.get('1.0',tk.END))
    minute=int(txtMin.get('1.0',tk.END))
    sec=int(txtSec.get('1.0',tk.END))
    while True:
        time2=time.localtime()
        nowHr=time2.tm_hour
        nowMin=time2.tm_min
        nowSec=time2.tm_sec
        if nowHr==hr:
            if nowMin ==minute:
                if nowSec==sec:
                    playsound.playsound('D:/Python/Project/Alarm.mp3')
                    break
    
window.columnconfigure([0,2],minsize=70)

lbHr=tk.Label(text='Hour',font='italic')
lbHr.grid(row=0,column=0)

lbMin=tk.Label(text='Min',font='italic')
lbMin.grid(row=0,column=1)

lbSec=tk.Label(text='Sec',font='italic')
lbSec.grid(row=0,column=2)

txtHr=tk.Text(fg='white',bg='blue',width='2',height='1')
txtHr.grid(row=1,column=0,pady=5)

txtMin=tk.Text(fg='white',bg='blue',width='2',height='1')
txtMin.grid(row=1,column=1)

txtSec=tk.Text(fg='white',bg='blue',width='2',height='1')
txtSec.grid(row=1,column=2)

lbHow=tk.Label(text='The clock first show you the current time, \nnow type in the time of the alarm.')
lbHow.grid(row=2,columnspan=3)

butStart=tk.Button(text='Set alarm clock',command=submit)
butStart.grid(row=3,columnspan=3,pady=5)

t=time.localtime()
txtHr.insert('1.0',str(t.tm_hour))
txtMin.insert('1.0',str(t.tm_min))
txtSec.insert('1.0',str(t.tm_sec))

window.mainloop()

When I set the alarm clock and the window goes for more than 5 seconds, it stops responding:

enter image description here

Surprisingly, it still works and the alarm still rings. Of course, having a non responding window is not ideal, so how can I fix this? Should I use datetime module, is there even any difference?

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
caterNaf
  • 13
  • 3
  • 1
    It is going through a while loop. Loops mess with ```mainloop```. You should start it on a new thread, or use ```.after(1000,function)``` –  Jul 10 '21 at 11:36
  • @Sujay Also only loops that take a long time to execute mess with `tkinter`. It's fine to have while loops as long as they don't take a lot of time. – TheLizzard Jul 10 '21 at 12:20
  • @caterNaf Why are you using `tk.Text` widgets instead of `tk.Entry` widgets. – TheLizzard Jul 10 '21 at 12:21
  • It quite possible the the `playsound` module does play well with `tkinter` — i.e. they're incompatible. My experience had been that `tkinter` doesn't like most sound/auto modules. You should write a very short test program and see if it's possible to use them both. – martineau Jul 10 '21 at 12:23

1 Answers1

1

You can use threading module and start the while loop on new thread:

import time,threading
import tkinter as tk
import playsound

window=tk.Tk()
window.title('Alarm clock')

#where the problem lies
def submit():
    hr=int(txtHr.get('1.0',tk.END))
    minute=int(txtMin.get('1.0',tk.END))
    sec=int(txtSec.get('1.0',tk.END))
    while True:
        time2=time.localtime()
        nowHr=time2.tm_hour
        nowMin=time2.tm_min
        nowSec=time2.tm_sec
        if nowHr==hr:
            if nowMin ==minute:
                if nowSec==sec:
                    playsound.playsound('D:/Python/Project/Alarm.mp3')
                    break
    

window.columnconfigure([0,2],minsize=70)

lbHr=tk.Label(text='Hour',font='italic')
lbHr.grid(row=0,column=0)

lbMin=tk.Label(text='Min',font='italic')
lbMin.grid(row=0,column=1)

lbSec=tk.Label(text='Sec',font='italic')
lbSec.grid(row=0,column=2)

txtHr=tk.Text(fg='white',bg='blue',width='2',height='1')
txtHr.grid(row=1,column=0,pady=5)

txtMin=tk.Text(fg='white',bg='blue',width='2',height='1')
txtMin.grid(row=1,column=1)

txtSec=tk.Text(fg='white',bg='blue',width='2',height='1')
txtSec.grid(row=1,column=2)

lbHow=tk.Label(text='The clock first show you the current time, \nnow type in the time of the alarm.')
lbHow.grid(row=2,columnspan=3)

butStart=tk.Button(text='Set alarm clock',command=lambda: [threading.Thread(target=submit).start()])
butStart.grid(row=3,columnspan=3,pady=5)


t=time.localtime()
txtHr.insert('1.0',str(t.tm_hour))
txtMin.insert('1.0',str(t.tm_min))
txtSec.insert('1.0',str(t.tm_sec))


window.mainloop()