I am trying to invoke default widget behavior on demand. Based on this answer I know a bit about bindtags, and taglists.
Let's say for example I have two buttons, and I want to have the bindtag behavior of a specific item in its taglist, of first button, whenever I left click on the right button:
import tkinter as tk
root = tk.Tk()
first_btn = tk.Button(root, text="1st")
second_btn = tk.Button(root, text="2nd")
second_btn.bind("<Button-1>", "expect the bindtag operation here")
first_btn.pack()
second_btn.pack()
root.mainloop()
I haven't specified command=...
for first_btn
as I need to have the very effect of button push for example with my second_btn
binding.
or as another example, I want to have second_btn
to invoke all(ideally of my choosing) bindtag callbacks of first_btn
:
import tkinter as tk
root = tk.Tk()
first_btn = tk.Button(root, text="1st")
second_btn = tk.Button(root, text="2nd", command="first_btn bindtag callbacks")
first_btn.pack()
second_btn.pack()
root.mainloop()
Or, what are reference names(if any) to the operations attached to bindtags?
To invoke the callback bound to a given sequence (e.g. <Button-1>
), you can do widget.event_generate(<sequence>, **kwargs)
. The optional keyword arguments can be x=0
, y=0
for a <Button-1>
event for instance. This will trigger all callbacks associated with the sequence (it does not matter whether they were bound with bind
, bind_class
or bind_all
).
In the below example, when the second button is clicked, it lowers the first one as if it were clicked too:
import tkinter as tk
root = tk.Tk()
first_btn = tk.Button(root, text="1st")
second_btn = tk.Button(root, text="2nd", command=lambda: first_btn.event_generate('<Button-1>'))
first_btn.pack()
second_btn.pack()
root.mainloop()
However, when doing tests interactively from the command line, generating keyboard events often does not work because the widget does not have keyboard focus. So, with the following code, when clicking on the button, the View
menu will open as if we had done Alt+v
:
import tkinter as tk
root = tk.Tk()
menubar = tk.Menu(root)
viewMenu = tk.Menu(menubar, tearoff=0)
viewMenu.add_command(label="Item 1")
viewMenu.add_command(label="Item 2")
menubar.add_cascade(menu=viewMenu, label="View", underline=0)
root.config(menu=menubar)
tk.Button(root, text='Test', command=lambda: root.event_generate('<Alt-v>')).pack()
root.mainloop()
But when I do root.event_generate('<Alt-v>')
from the IPython QtConsole, nothing happens. The workaround is to force keyboard focus before generating the event:
root.focus_force()
root.event_generate('<Alt-v>')