How to use default bindtag behavior as methods?

2020-02-16 04:45发布

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?

1条回答
该账号已被封号
2楼-- · 2020-02-16 05:22

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>')
查看更多
登录 后发表回答