user3527876
user3527876

Reputation: 11

making tkinter entry box value into a float (python)

I am a beginner. I have tried everything to make the following code take numeric inputs into entry boxes and do a calculation with them. I am getting the ValueError and nothing I do makes that stop happening. This is supposed to be a program that calculates monthly interest payments and a total paid out. I am keeping it at a simple product until I fix this much more basic problem. Thanks.

def multiply(var1, var2, var3):
    product = float(var1 * var2 * var3)
    return product


def btnClick(event):
    x = float(entry.get())


main = Tk()
main.title("Assignment 16")

main.geometry("500x500")
main["bg"] = "#000066"

lblFirst = Label(main, text="Amount to Pay: ")
lblFirst.grid(row=0, column=3, pady=5)
entry = Entry(main, width=20)
entry.grid(row=0, column=4)
amount = entry.get()
lblSecond = Label(main, text="Interest Rate (like 7.5): ")
lblSecond.grid(row=2, column=3, pady=10)
entry2 = Entry(main, width=20)
entry2.grid(row=2, column=4)
rate = entry2.get()
lblThird = Label(main, text="Years to Pay: ")
lblThird.grid(row=4, column=3, pady=15)
entry3 = Entry(main, width=20)
entry3.grid(row=4, column=4)
years = entry3.get()

try:
    # Try to make it a float
    if amount.isnumeric():
        amount = float(amount)

except ValueError:
    # Print this if the input cannot be made a float
    print("Bad input")

try:
    # Try to make it a float
    if rate.isnumeric():
        rate = float(rate)

except ValueError:
    # Print this if the input cannot be made a float
    print("Bad input")

try:
    # Try to make it a float
    if years.isnumeric():
        years = int(years)

except ValueError:
    # Print this if the input cannot be made a float
    print("Bad input")

lblFourth = Label(main, text="Monthly Payment: ")
lblFourth.grid(row=6, column=3, pady=15)
lblFourthTwo = Label(main, text="XXXXX")
lblFourthTwo.grid(row=6, column=4)
lblFifth = Label(main, text="Total of Paymenta: ")
lblFifth.grid(row=8, column=3, pady=15)
lblFifthTwo = Label(main, text="XXXXX")
lblFifthTwo.grid(row=8, column=4)

button1 = Button(main, text='Convert', width=10, command=btnClick)
button2 = Button(main, text='Calculate', width=10, command=multiply(amount, rate, years))
button1.grid(padx=20, pady=20)

main.mainloop()

Upvotes: 0

Views: 2703

Answers (1)

Roland Smith
Roland Smith

Reputation: 43563

All your code runs before the mainloop starts.

Programs using GUI-toolkits like tkinker are event-driven. Your code only runs in the set-up before the mainloop and after that in event-handlers.

You can use validation to ensure that only numbers are entered.

Working example (for Python 3) below. This also shows how to get the value from an editbox in an event handler and how to create synthetic events to update other widgets.

import tkinter as tk
from tkinter import ttk

# Creating and placing the widgets
root = tk.Tk()
root.wm_title('floating point entry')
qedit = ttk.Entry(root, justify='right')
qedit.insert(0, '100')
qedit.grid(row=0, column=0, sticky='ew')
result = ttk.Label(root, text='100')
result.grid(row=1, column=0)
ttk.Button(root, text="Exit", command=root.quit).grid(row=2, column=0)


# Callback functions
def is_number(data):
    if data == '':
        return True
    try:
        float(data)
        print('value:', data)
    except ValueError:
        return False
    result.event_generate('<<UpdateNeeded>>', when='tail')
    return True


def do_update(event):
    w = event.widget
    number = float(qedit.get())
    w['text'] = '{}'.format(number)

# The following settings can only be done after both the
# widgets and callbacks have been created.
vcmd = root.register(is_number)
qedit['validate'] = 'key'
qedit['validatecommand'] = (vcmd, '%P')
result.bind('<<UpdateNeeded>>', do_update)

# Run the event loop.
root.mainloop()

Upvotes: 1

Related Questions