pythontkinteroptionmenu

Is there a way to execute a function ONLY if the option of a tkinter optionmenu is changed?


When using tkinter OptionMenu the command input lets you activate a function, but the same function activates even when you click on the already set option. Example: option "A" is set, you click again on option "A" the command activates, however I would like it to happen only if I change the selection from "A" to another option that isn't "A" like "B" or "C" and viceversa.

Here's my code:

import tkinter 
from tkinter import *

# Create window------------------------------------------
window = tkinter.Tk()
window.title("Window")
window.geometry("800x500")
#--------------------------------------------------------

# Function-----------------------------------------------
def print_message(*args):
    print("the option has been changed")
#--------------------------------------------------------

# Dropdown menu------------------------------------------
# Datatype
option_selected = StringVar()  
# Create dropdown menu
option_list = ["A", "B", "C"]
option_selected.set(option_list[0]) 
option_menu = OptionMenu(window, option_selected, *option_list)
option_menu.pack()
option_selected.trace("w",print_message)
#--------------------------------------------------------

# Maintain window open
window.mainloop()

Solution

  • Basically OptionMenu does not support such feature, however you can create a custom OptionMenu to provide such feature:

    import tkinter as tk
    
    class CustomOptionMenu(tk.OptionMenu):
        def __init__(self, master, var, *values, command=None):
            super().__init__(master, var, *values,
                             command=self.on_selected if command else None)
            self.command = command
            self.value = var.get()
    
        def on_selected(self, value):
            # execute callback only if selected value is changed
            if self.value != value:
                self.command(value)
                self.value = value  # save the selected value
    
    # Create window------------------------------------------
    window = tk.Tk()
    window.title("Window")
    window.geometry("800x500")
    #--------------------------------------------------------
    
    # Function-----------------------------------------------
    def print_message(value):
        print(f"the option has been changed to {value}")
    #--------------------------------------------------------
    
    # Dropdown menu------------------------------------------
    # Datatype
    option_selected = tk.StringVar()
    # Create dropdown menu
    option_list = ["A", "B", "C"]
    option_selected.set(option_list[0])
    option_menu = CustomOptionMenu(window, option_selected, *option_list, command=print_message)
    option_menu.pack()
    #--------------------------------------------------------
    
    # Maintain window open
    window.mainloop()