1

So, I'm working on a timer using Python and Tkinter's GUI. To do so, I intend to convert the minutes into seconds (as seen in my code) and use Python's time.sleep command to count down (not yet implemented).

from tkinter import *
import time
countdown = Tk()
countdown.geometry('500x300')
minute = Text(countdown, height = 0.01, width = 5)
minute.place(x=100, y=100)
minlabel = Label(text = "Input Minutes", font = ("MS Sans Serif", 10), bg = 'Light Blue')
minlabel.place(x=85, y = 80)
def go(event):
    minseconds = int(minute.get("1.0", END))*60
    print(int(minseconds)) 
countdown.bind('<Return>', go)
countdown.mainloop()

However, when I convert it to minutes, it works the first time (I.E, when I input 3, 180 returns), but any time after that I get this:

ValueError: invalid literal for int() with base 10: '3\n3\n\n'

Any idea what could be causing this? And why it works the first time but then stops working? Thanks :)

1
  • 3
    this '3\n3\n\n' contains more than numbers. '\n' means a line break point, you need to filter the string in the way you want to work with. Maybe dont use tk.END rather an known index. Commented May 31, 2021 at 13:51

3 Answers 3

2

The problem is every time Enter is pressed a newline character is entered into the Text widget named minute and they mess up the conversion to int.

The simplest way I can think of to avoid that would be to just clear the widget in the event handler function:

def go(event):
    minseconds = int(minute.get("1.0", END))*60
    print(int(minseconds))
    minute.delete('1.0', END)  # <---- ADDED.

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

Comments

1

so actually the error is quite simple. You created a Text widget, which is just adding lines when you press Enter (corresponding to the \n characters). Just make your text widget bigger (instead of height = 0.01 maybe 2) and you will see it.

To do it more elegantly, you might try Entry() instead of Text(). See the example.

import time
import tkinter as tk

def go(event):
    minseconds = int(min_entry.get())
    seconds = minseconds*60
    print(int(seconds))

countdown = tk.Tk()
countdown.geometry('500x300')

minlabel = tk.Label(text = "Input Minutes", font = ("MS Sans Serif", 10), bg = 'Light Blue')
minlabel.place(x=85, y = 80)
min_entry = tk.Entry()
min_entry.place(x=100, y=100)

countdown.bind('<Return>', go)
countdown.mainloop()

Furthermore try to put your functions always on top of your code, as they have to be defined before you call them. This might be causing trouble as you code gets bigger.

Hope you get a better understanding from tkinter by this :)

Comments

1

Check this update function. Import the module at top

import messagebox as msg
def go(event):
    try:
        minseconds = int(minute.get("1.0", END))*60
        print(int(minseconds)) 
        minute.delete("1.0", END)
   except Exception:
        msg.showerror("Error","invalid input provided.")
        minute.delete("1.0", END)

But I would suggest to go with Entry With a StringVar()

from tkinter import *
from tkinter import messagebox as msg
countdown = Tk()
countdown.geometry('500x300')
minute=StringVar()
minut = Entry(countdown,textvariable=minute, width = 5)
minut.place(x=100, y=100)
minlabel = Label(text = "Input Minutes", font = ("MS Sans Serif", 10), bg = 'Light Blue')
minlabel.place(x=85, y = 80)
def go(event):
    try:
        minseconds = int(minute.get())*60
        print(int(minseconds)) 
        minute.set("")
    except ValueError:
        msg.showerror("Error","Invalid input provided.")
countdown.bind('<Return>', go)
countdown.mainloop()

Comments

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.