2

I have created a medicine reminder in tkinter.It works but as I click the button "Notify", my program freezes and says not responding but the program still works.

from tkinter import *
from plyer import notification
from datetime import datetime
import tkinter.messagebox as msg

root = Tk()
root.title("Medicine reminder")


def notify():
    msg.showinfo("Reminder Set",f"You will be notified at {timeSlider.get()}. Make sure that you don't close the program")
    while True:
        hour = datetime.now().hour
        if hour == timeSlider.get():
            notification.notify(
                title=f"Take your medicine {medicine.get()}",
                message=f"You have scheduled it for {timeSlider.get()}",
                # displaying time
                timeout=15)
            break


Label(text="Medicine Reminder", font="comicsans 20 bold").pack(anchor="w", padx=10, pady=10)
medicine = StringVar()
medicine_entry = Entry(font="comicsans 20", textvariable=medicine)
medicine_entry.insert(0, "Name of medicine")
medicine_entry.pack(anchor="w", padx=10, pady=5)
timeSlider = Scale(from_=0, to=24, orient=HORIZONTAL)
Label(text="Enter the time you want to get notified at:", font="comicsans 15").pack(anchor="w", padx=10)
timeSlider.pack(anchor="w", padx=10)
Button(text="Notify me", font="comicsans 15 bold", relief=SUNKEN, borderwidth=6, command=notify).pack(anchor="w",
                                                                                                      pady=15, padx=10)

root.mainloop()
2
  • I think the while loop is causing the problem, try using after Commented Aug 29, 2020 at 9:50
  • Can u tell how to use after...but it should work with while loop also..how can I make it work with while loop Commented Aug 29, 2020 at 9:52

1 Answer 1

1

The problem with your code was that, you used an infinity loop with while which runs on the same thread as tkinter, hence it cannot run the window as the window is busy doing the while loop, using after which tkinter has inbuilt is one of the ways to tackle this problem.

Method 1 (using after):

def notify():
    global hour
    msg.showinfo("Reminder Set",f"You will be notified at {timeSlider.get()}. Make sure that you don't close the program")
    hour = datetime.now().hour
    root.after(timeSlider.get()*3600000,alert) #converting hour to ms

def alert():    
    notification.notify(
        title=f"Take your medicine {medicine.get()}",
        message=f"You have scheduled it for {timeSlider.get()}",
        # displaying time
        timeout=15)

after() method takes two arguments mainly:

  • ms - time to be run the function
  • func - the function to run after the given ms is finished.

The remaining part of the code remains the same

Method 2 (Threading):

import threading
....
Button(text="Notify me", font="comicsans 15 bold", relief=SUNKEN, borderwidth=6, command=threading.Thread(target=notify).start).pack(anchor="w",

Just make the change to the buttons command argument and the rest of the code, stays still. This will do the trick, but then with threading it might still look inefficient, so I recommend using method 1.

Hope you got your doubts cleared, if any more errors, do let me know.

Cheers

Sign up to request clarification or add additional context in comments.

5 Comments

What is this after...can you explain and we cannot write this with the help of while loop
Well I did a Google search about root.after and I understood root.after. Thanks, that's how we learn new things.
But timeslider.get is already in integer form so there is no need to typecast it
@Vasu Threading is nothing much, just like a normal thread, imagine cars going through a thread and they got into accident, so the thread might break, just like that, your tkinter runs on one thread and your while loop runs with it causing the thread to freeze, but with threading you make a new thread for that function with while and hence the thread with tkinter is going smooth, while the thread with while loop is frozen, and it doesnt matter for the other thread.
I request you to please upvote the question as StackOverflow is not allowing me to ask more questions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.