How to run a code whenever a Tkinter widget value changes?

Viewed 27661

I'm using Python and Tkinter, and I want the equivalent of onchange event from other toolkits/languages. I want to run code whenever the user updates the state of some widgets.

In my case, I have many Entry, Checkbutton, Spinbox and Radiobutton widgets. Whenever any one of these changes, I want to run my code (in this case, update a text box on the other panel).

(just remember that user may interact with those widgets using either mouse or keyboard, and even using Ctrl+V to paste text)

5 Answers

You have three different ways of doing the same:

1) Use the built-in "command" configuration, like the one you use on buttons

import tkinter as tk
from tkinter import messagebox as tk_messagebox

def spinbox1_callback():
    tk_messagebox.showinfo("Spinbox callback", "You changed the spinbox.")

if __name__ == "__main__":
    master = tk.Tk()
    spinbox1 = tk.Spinbox(master, from_=0, to=10, command=spinbox1_callback)
    spinbox1.pack()
    tk.mainloop()

2) Use the event bindings to capture specific events: http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm

import tkinter as tk
from tkinter import messagebox as tk_messagebox

root = tk.Tk()

def callback(event):
    tk_messagebox.showinfo("clicked at", event.x, event.y)

frame = tk.Frame(root, width=100, height=100)
frame.bind("<Button-1>", callback)
frame.pack()

root.mainloop()

3) "trace" changes on a tkinter variable classes, so if your widget uses a StringVar, BooleanVar, IntVar, or DoubleVar in the textvariable parameter, you will get a callback once it gets updated. https://effbot.org/tkinterbook/variable.htm

import tkinter as tk
from tkinter import messagebox as tk_messagebox


if __name__ == "__main__":
    master = tk.Tk()
    widget_contents = tk.StringVar()
    widget_contents.set('')
    some_entry = tk.Entry(master,textvariable=widget_contents,width=10)
    some_entry.pack()

    def entry1_callback(*args):
        tk_messagebox.showinfo("entry callback", "You changed the entry %s" % str(args))
        some_entry.update_idletasks()

    widget_contents.trace('w',entry1_callback)

    tk.mainloop()
Related