简体   繁体   中英

How to put the value entered in a Tkinter textbox into a function argument in Python?

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()

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()

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" .

You can set the default value of the count argument to None and initialize it to the value based on the value of time_box inside countdown() if count is None :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM