I am using a tkk.Combobox themed widget in Python 3.5.2. I want an action to happen when a value is selected.
In the Python docs, it says:
The combobox widgets generates a
<<ComboboxSelected>>
virtual event when the user selects an element from the list of values.
Here on the Stack, there are a number of answers (1, 2, etc) that show how to bind the event:
cbox.bind("<<ComboboxSelected>>", function)
However, I can't make it work. Here's a very simple example demonstrating my non-functioning attempt:
import tkinter as tk
from tkinter import ttk
tkwindow = tk.Tk()
cbox = ttk.Combobox(tkwindow, values=[1,2,3], state='readonly')
cbox.grid(column=0, row=0)
cbox.bind("<<ComboboxSelected>>", print("Selected!"))
tkwindow.mainloop()
I get one instance of "Selected!" immediately when I run this code, even without clicking anything. But nothing happens when I actually select something in the combobox.
I'm using IDLE in Windows 7, in case it makes a difference.
What am I missing?
Use ttk. Combobox(root, textvariable) to create a combobox. Set the state property to readonly to prevent users from entering custom values. A combobox widget emits the '<<ComboboxSelected>>' event when the selected value changes.
ttk is a module that is used to style the tkinter widgets. Just like CSS is used to style an HTML element, we use tkinter. ttk to style tkinter widgets.
We can select any option in the dropdown list. Now add state = "readonly" in the Combobox object, it will make the Combobox Entry Widget disabled.
The problem is not with the event <<ComboboxSelected>>
, but the fact that bind
function requires a callback as second argument.
When you do:
cbox.bind("<<ComboboxSelected>>", print("Selected!"))
you're basically assigning the result of the call to print("Selected!")
as callback.
To solve your problem, you can either simply assign a function object to call whenever the event occurs (option 1, which is the advisable one) or use lambda functions (option 2).
Here's the option 1:
import tkinter as tk
from tkinter import ttk
tkwindow = tk.Tk()
cbox = ttk.Combobox(tkwindow, values=[1,2,3], state='readonly')
cbox.grid(column=0, row=0)
def callback(eventObject):
print(eventObject)
cbox.bind("<<ComboboxSelected>>", callback)
tkwindow.mainloop()
Note the absence of ()
after callback
in: cbox.bind("<<ComboboxSelected>>", callback)
.
Here's option 2:
import tkinter as tk
from tkinter import ttk
tkwindow = tk.Tk()
cbox = ttk.Combobox(tkwindow, values=[1,2,3], state='readonly')
cbox.grid(column=0, row=0)
cbox.bind("<<ComboboxSelected>>", lambda _ : print("Selected!"))
tkwindow.mainloop()
Check what are lambda functions and how to use them!
Check this article to know more about events and bindings:
http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
Thanks you for the posts. I tried *args and it workes with bind and button as well:
import tkinter as tk
from tkinter import ttk
tkwindow = tk.Tk()
cbox = ttk.Combobox(tkwindow, values=[1,2,3], state='readonly')
def callback(*args):
print(eventObject)
cbox.bind("<<ComboboxSelected>>", callback)
btn = ttk.Button(tkwindow, text="Call Callback", command=callback);
tkwindow.mainloop()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With