Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Tkinter update when entry is changed

Tags:

python

tkinter

I'm trying to make a simple temperature conversion calculator in python. What I want to do is to be able to type in a number, and have the other side automatically update, without having to push a button. Right now I can only get it to work in one direction. I can either code it so that it can go from F to C, or C to F. But not either way.

Obviously after is not the way to go. I need some kind of onUpdate or something. TIA!

import Tkinter as tk

root = tk.Tk()
temp_f_number = tk.DoubleVar()
temp_c_number = tk.DoubleVar()

tk.Label(root, text="F").grid(row=0, column=0)
tk.Label(root, text="C").grid(row=0, column=1)

temp_f = tk.Entry(root, textvariable=temp_f_number)
temp_c = tk.Entry(root, textvariable=temp_c_number)

temp_f.grid(row=1, column=0)
temp_c.grid(row=1, column=1)

def update():
    temp_f_float = float(temp_f.get())
    temp_c_float = float(temp_c.get())

    new_temp_c = round((temp_f_float - 32) * (5 / float(9)), 2)
    new_temp_f = round((temp_c_float * (9 / float(5)) + 32), 2)

    temp_c.delete(0, tk.END)
    temp_c.insert(0, new_temp_c)

    temp_f.delete(0, tk.END)
    temp_f.insert(0, new_temp_f)

    root.after(2000, update)

root.after(1, update)
root.mainloop()
like image 361
drewd423 Avatar asked Feb 17 '14 19:02

drewd423


People also ask

How do I get an event callback when a tkinter entry widget is modified?

We will create an event callback function by specifying the variable that stores the user input. By using the trace("mode", lambda variable, variable: callback()) method with the variable, we can trace the input on the Label widget in the window.

What does update () do in tkinter?

Update method processes all the pending idle tasks, unvisited events, calling functions, and callbacks. The method is applicable for updating and processing all the events or tasks such as redrawing widgets, geometry management, configuring the widget property, etc.

How do I update tkinter?

As previously stated, the best way to get the latest version of Tkinter is to install Python 3.7 or later. But Tkinter can also be downloaded and installed as part of any standard Python 3 installation.

What is IntVar () in tkinter?

_ClassType IntVarConstruct an integer variable. set(self, value) Set the variable to value, converting booleans to integers. get(self) Return the value of the variable as an integer.


2 Answers

What you are looking for is variable trace() method. E.g.:

def callback(*args):
    print "variable changed!"

var = DoubleVar()
var.trace("w", callback)

Attach trace callbacks for each of your DoubleVar, for temp_f_number one to update the temp_c_number value and vice versa. You'll likely also need to disable one callback function while inside another one, to avoid recursive update cycle.

Another note - do not edit the Entry fields. Instead, use variables' set() method. Entry fields will be updated automatically.

So, complete code could look like this:

import Tkinter as tk

root = tk.Tk()
temp_f_number = tk.DoubleVar()
temp_c_number = tk.DoubleVar()

tk.Label(root, text="F").grid(row=0, column=0)
tk.Label(root, text="C").grid(row=0, column=1)

temp_f = tk.Entry(root, textvariable=temp_f_number)
temp_c = tk.Entry(root, textvariable=temp_c_number)

temp_f.grid(row=1, column=0)
temp_c.grid(row=1, column=1)

update_in_progress = False

def update_c(*args):
    global update_in_progress
    if update_in_progress: return
    try:
        temp_f_float = temp_f_number.get()
    except ValueError:
        return
    new_temp_c = round((temp_f_float - 32) * 5 / 9, 2)
    update_in_progress = True
    temp_c_number.set(new_temp_c)
    update_in_progress = False

def update_f(*args):
    global update_in_progress
    if update_in_progress: return
    try:
        temp_c_float = temp_c_number.get()
    except ValueError:
        return
    new_temp_f = round(temp_c_float * 9 / 5 + 32, 2)
    update_in_progress = True
    temp_f_number.set(new_temp_f)
    update_in_progress = False

temp_f_number.trace("w", update_c)
temp_c_number.trace("w", update_f)

root.mainloop()
like image 182
glexey Avatar answered Oct 17 '22 20:10

glexey


.trace is soon to be deprecated, use .trace_add instead:

var = tk.StringVar()
var.trace_add('write', callback)

Same functionality, but you must pass write or read instead of w or r.

like image 30
tralph3 Avatar answered Oct 17 '22 22:10

tralph3