from tkinter import * # Trial 3 - OptionMenu with a trace (auto-updating label) # Purpose: Learn how to make the UI respond instantly when a dropdown # value changes, WITHOUT needing a button press. # A "trace" calls a function every time the StringVar changes. UNITS = ["km", "m", "cm", "mm"] class DropdownTrial: def __init__(self): self.frame = Frame(padx=10, pady=10) self.frame.grid() self.heading = Label(self.frame, text="Dropdown Trial - v3 (Auto-Update Trace)", font=("Arial", "16", "bold")) self.heading.grid(row=0) instructions = ("Change either dropdown and watch the label " "update automatically - no button needed!") Label(self.frame, text=instructions, wraplength=300, font=("Arial", "11"), fg="#666666").grid(row=1, pady=5) # --- From unit --- from_frame = Frame(self.frame) from_frame.grid(row=2, pady=5) Label(from_frame, text="Convert from:", font=("Arial", "12")).grid(row=0, column=0, padx=(0, 10)) self.from_var = StringVar(value=UNITS[0]) # trace_add fires whenever the variable is written to self.from_var.trace_add("write", self.update_label) OptionMenu(from_frame, self.from_var, *UNITS).grid(row=0, column=1) # --- To unit --- to_frame = Frame(self.frame) to_frame.grid(row=3, pady=5) Label(to_frame, text="Convert to: ", font=("Arial", "12")).grid(row=0, column=0, padx=(0, 10)) self.to_var = StringVar(value=UNITS[1]) self.to_var.trace_add("write", self.update_label) OptionMenu(to_frame, self.to_var, *UNITS).grid(row=0, column=1) # --- Auto-updating result label --- self.result_label = Label(self.frame, text="", font=("Arial", "13", "bold"), fg="#004C99") self.result_label.grid(row=4, pady=15) # Call once at startup so the label shows something immediately self.update_label() def update_label(self, *args): """ Called automatically whenever from_var or to_var changes. *args is required because trace passes extra arguments we don't need. """ from_unit = self.from_var.get() to_unit = self.to_var.get() if from_unit == to_unit: self.result_label.config( text="Please choose two different units", fg="#9C0000" ) else: self.result_label.config( text=f"Ready to convert: {from_unit} \u2192 {to_unit}", fg="#004C99" ) # main routine if __name__ == "__main__": root = Tk() root.title("Dropdown Trial v3") DropdownTrial() root.mainloop()