0

I created this GUI notifier, that I have to give it a task in the task_box and the needed time in the time_box, and it will countdown until 0 and will notify the task that I gave it at the beginning. However there's a bug that I can't seem to figure out (even after a lot of research), I can't set the time that I want, because the count is an argument in countdown function, it doesn't accept the value of the time_box.get() as an argument, I can only edit the code (like set the time in the countdown(count=10) function)

Code:

import time
from tkinter import *
from plyer import notification
from tkinter import messagebox

def space():
    space = Label(text="", bg="darkgreen")
    space.grid()

def countdown(count=10):
    if task_box.get() != "" and time_box.get() != "" and time_box.get().isdigit():
        # count = 60 * int(time_box.get())
        count_label["text"] = count
        if count > 0:
            root.after(1000, countdown, count-1)
        if count == 0:
            set_notifier()
    else:
        messagebox.showwarning(title="Error", message="Please set task and / or time")


def set_notifier():

    notification.notify(

        title = f"{task_box.get()}",
        message = "Don't be stupid, just do what I say!",
        timeout=3

    )


root = Tk()
# root.iconbitmap("yt.ico")
root.title("Notifier")
root.geometry("400x400")
root.columnconfigure(0, weight=1)
root.config(bg="darkgreen")

space()
space()
space()

task_label = Label(root, text="Enter task", bg="darkgreen", fg="white", font=("jost", 9, "bold"))
task_label.grid()

EntryVar = StringVar()
task_box = Entry(root, width=27, textvariable=EntryVar)
task_box.grid()

space()

time_label = Label(root, text="Set time (minutes)", bg="darkgreen", fg="white", font=("jost", 9, "bold"))
time_label.grid()

EntryVar = StringVar()
time_box = Entry(root, width=27, textvariable=EntryVar)
time_box.grid()

space()
space()

set_btn = Button(width=23, height=1, bg="darkgreen", fg="white", text="Set", font=("jost", 11, "bold"), command=countdown)
set_btn.grid()

space()

count_label = Label(root, text="", bg="darkgreen", fg="white")
count_label.grid()

space()
space()


root.bind('<Return>', set_notifier)
root.mainloop()
4
  • where do you want to use it? Id in comman= then create new function with countdown( int(time_box.get()) ) and assign this function to comman=, or use command=lambda:countdown( int(time_box.get()) ) Commented Nov 22, 2021 at 2:18
  • always put full error message (starting at word "Traceback") in question (not in comments) as text (not screenshot, not link to external portal). There are other useful information. Commented Nov 22, 2021 at 2:19
  • time_box keeps it as string and you have to convert to integer int(...) Commented Nov 22, 2021 at 2:21
  • you assigned EntryVar to time_box and task_box but you never use it - you can remove it. If you want to use it then use different name for StringVar in time_box and different name for StringVar in task_box Commented Nov 22, 2021 at 2:26

2 Answers 2

2

command= expects function name without arguments but you can always create other function which doesn't get arguments but it runs your function with argument(s):

def start_countdown():
    countdown( int(time_box.get()) )

Button(..., command=start_countdown )

You can also use lambda for this

start_countdown = lambda : countdown( int(time_box.get()) )

Button(..., command=start_countdown )

or simpler

Button(..., command=lambda:countdown(int(time_box.get())) )

BTW:

time_box.get() gives string so you have to remeber to convert to integer.

But user may set text hello instead of number and then it may raise error - so better use try/except - and this need normal function.

def start_countdown():
    try:
       countdown( int(time_box.get()) )
    except ValueError as ex:
       print('ex:', ex)
       messagebox.showwarning(title="Error", message="Wrong time value")

Button(..., command=start_countdown )

You could also use start_countdown() to check task_box.get() so you wouldn't have to do it in countdown().

Checking entry values in countdown() makes other problem. Every 1 second it gets value from Entry and checks it - so if you change value when it counts down then it may run messagebox with "Please set task and / or time".

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

1 Comment

Best solution, I only had to use this > def start_countdown(): countdown( int(time_box.get()) )
1

Your problem was caused by using a Button to call countdown(count=10) because button command does not take a parameter and count=10 is a kwd not a arg.

Solution

Call countdown(count) indirectly with counter()

def countdown(count):
    count_label["text"] = count
    if count > 0:
        root.after(1000, countdown, count-1)
    else:
        set_notifier()

def counter():
    if task_box.get() != "":
        count = time_box.get()
        if count != "" and count.isdigit() and int(count ) > 0:
            count = 60 * int(time_box.get())
            countdown(count)
        else:
            messagebox.showwarning(title = "Error", message = "Please set time time")
            time_box.focus_set()
    else:
        messagebox.showwarning(title = "Error", message = "Please set task event")
        task_box.focus_set()

Also change set_btn command like so.

set_btn = Button(
    width = 23, height = 1, bg = "darkgreen", fg = "white", text = "Set",
    font = ("jost", 11, "bold"), command = counter)
set_btn.grid()

task_box.focus_set()

1 Comment

Great solution, thank you very much!

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.