How to detect when an OptionMenu or Checkbutton change?
Question:
My tkinter application has several controls, and I’d like to know when any changes occur to them so that I can update other parts of the application.
Is there anything that I can do short of writing an updater function, and looping at the end with:
root.after(0, updaterfunction)
This method has worked in the past but I’m afraid that it might be expensive if there are many things to check on.
Even if I did use this method, could I save resources by only updating items with changed variables? If so, please share how, as I’m not sure how to detect specific changes outside of the update function.
Answers:
Many tkinter controls can be associated with a variable. For those you can put a trace on the variable so that some function gets called whenever the variable changes.
Example:
In the following example the callback will be called whenever the variable changes, regardless of how it is changed.
def callback(*args):
print(f"the variable has changed to '{var.get()}'")
root = tk.Tk()
var = tk.StringVar(value="one")
var.trace("w", callback)
For more information about the arguments that are passed to the callback see this answer
To have an event fired when a selection is made set the command option for OptionMenu
ex.
def OptionMenu_SelectionEvent(event): # I'm not sure on the arguments here, it works though
## do something
pass
var = StringVar()
var.set("one")
options = ["one", "two", "three"]
OptionMenu(frame, var, *(options), command = OptionMenu_SelectionEvent).pack()
This will print the dropdown selection to the console. but my suggestion is to avoid console in GUI based applications. create a text indicator and print output to it
use the function in below code
from tkinter import *
tk = Tk()
def OptionMenu_SelectionEvent(event):
print(var.get())
pass
var = StringVar(); var.set("one")
options = ["one", "two", "three"]
OptionMenu(tk, var, *(options), command = OptionMenu_SelectionEvent).pack()
tk.mainloop()
If you are using a Tkinter Variable class like StringVar()
for storing the variables in your Tkinter OptionMenu
or Checkbutton
, you can use its trace()
method.
trace()
, basically, monitors the variable when it is read from or written to.
The trace()
method takes 2 arguments – mode
and function callback
.
trace(mode, callback)
- The mode argument is one of “r” (call observer when variable is read by someone), “w” (call when variable is written by someone), or “u” (undefine; call when the variable is deleted).
- The callback argument is the call you want to make to the function when the variable is changed.
This is how it is used –
def callback(*args):
print("variable changed!")
var = StringVar()
var.trace("w", callback)
var.set("hello")
My tkinter application has several controls, and I’d like to know when any changes occur to them so that I can update other parts of the application.
Is there anything that I can do short of writing an updater function, and looping at the end with:
root.after(0, updaterfunction)
This method has worked in the past but I’m afraid that it might be expensive if there are many things to check on.
Even if I did use this method, could I save resources by only updating items with changed variables? If so, please share how, as I’m not sure how to detect specific changes outside of the update function.
Many tkinter controls can be associated with a variable. For those you can put a trace on the variable so that some function gets called whenever the variable changes.
Example:
In the following example the callback will be called whenever the variable changes, regardless of how it is changed.
def callback(*args):
print(f"the variable has changed to '{var.get()}'")
root = tk.Tk()
var = tk.StringVar(value="one")
var.trace("w", callback)
For more information about the arguments that are passed to the callback see this answer
To have an event fired when a selection is made set the command option for OptionMenu
ex.
def OptionMenu_SelectionEvent(event): # I'm not sure on the arguments here, it works though
## do something
pass
var = StringVar()
var.set("one")
options = ["one", "two", "three"]
OptionMenu(frame, var, *(options), command = OptionMenu_SelectionEvent).pack()
This will print the dropdown selection to the console. but my suggestion is to avoid console in GUI based applications. create a text indicator and print output to it
use the function in below code
from tkinter import *
tk = Tk()
def OptionMenu_SelectionEvent(event):
print(var.get())
pass
var = StringVar(); var.set("one")
options = ["one", "two", "three"]
OptionMenu(tk, var, *(options), command = OptionMenu_SelectionEvent).pack()
tk.mainloop()
If you are using a Tkinter Variable class like StringVar()
for storing the variables in your Tkinter OptionMenu
or Checkbutton
, you can use its trace()
method.
trace()
, basically, monitors the variable when it is read from or written to.
The trace()
method takes 2 arguments – mode
and function callback
.
trace(mode, callback)
- The mode argument is one of “r” (call observer when variable is read by someone), “w” (call when variable is written by someone), or “u” (undefine; call when the variable is deleted).
- The callback argument is the call you want to make to the function when the variable is changed.
This is how it is used –
def callback(*args):
print("variable changed!")
var = StringVar()
var.trace("w", callback)
var.set("hello")