Tkinter Binding a keyboard key to a button's command in python
If your binding calls the invoke
method of the button, then it will do nothing when the button is disabled. If the button is enabled, it will do whatever the button is designed to do. Of course, you could also just bind to a function that checks the state of the button before doing anything.
Here's a contrived example. It contains a button labelled "Count" which increments a counter and updates the display. There are two other buttons used to enable or disable this first button.
Once the window has focus, if you press the return key it will invoke the button. Notice that after you disable the button the return key does nothing. When you re-enable the button the return key works again.
import tkinter as tkCOUNT = 0def count(): global COUNT COUNT += 1 label.configure(text=f"Count: {COUNT}")root = tk.Tk()label = tk.Label(root, text="Count: 0")button = tk.Button(root, text="Count", command=count)enable_btn = tk.Button(root, text="Enable Count", command=lambda: button.configure(state="normal"))disable_btn = tk.Button(root, text="Disable Count", command=lambda: button.configure(state="disabled"))label.pack(side="top", fill="x", pady=20)button.pack(side="left", padx=(0,10))disable_btn.pack(side="right")enable_btn.pack(side="right")root.bind_all("<Return>", lambda event: button.invoke())root.mainloop()
A button's command can be invoked as
btn = tkinter.Button(command=lambda: print("Hello!"), text="Press me for greeting")btn.pack() # This is not required to allow invoke() to workbtn.invoke()
which calls the function. This works even if the button is not actually on-screen, as shown in the snippet.
However, it will not work if the button state is "disabled"
. I would recommend storing the function used in a separate variable in this case.
In the example below, the command for the button just calls a method belonging to the class. This means that you can call the function by pressing a button, or by calling the method directly, even if the button is disabled, hidden or deleted. The button simply looks at the current definition of the function and calls it.
import tkinter as tkclass Window(tk.Tk): def __init__(self): super().__init__() self.bind("<Return>", lambda event: self.current_button_function()) self.btn = tk.Button(self, text="Press me!", command=lambda: self.current_button_function()) # command=self.current_button_function won't work since it won't update when the function updates self.btn.pack() self.mainloop() def current_button_function(self): print("This is a function. Button click is now disabled but function is still callable and enter still works") self.btn.configure(state="disabled") #self.current_button_function = lambda: print("This is simple lambda") # For easily returning single expression def tmp(): # For a multi-line function print("This is another function which works even though the button is disabled! The button is no longer on the page but the function is still callable and enter still works") self.btn.forget() def tmp(): print("The button is not on the page but it doesn't matter!") #Could continue adding nested 'def' and/or 'lambda' self.current_button_function = tmp self.current_button_function = tmp if __name__ == "__main__": window = Window()
Try clicking the button and/or pressing enter a few times to see it change the callback function and still work even when the button is forgotten or disabled.