【问题标题】:How to use default bindtag behavior as methods?如何使用默认的绑定标签行为作为方法?
【发布时间】:2017-12-20 09:34:15
【问题描述】:

我正在尝试按需调用默认的小部件行为。基于this answer,我对绑定标签和标签列表有所了解。

假设我有两个按钮,并且我希望在其标记列表中的特定项目的第一个按钮上具有绑定标记行为,每当我左键单击右侧按钮时:

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()

我没有为first_btn 指定command=...,因为我需要具有按钮推送的效果,例如使用我的second_btn 绑定。


或者作为另一个例子,我想让second_btn 调用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()

或者,附加到绑定标签的操作的引用名称(如果有的话)是什么?

【问题讨论】:

  • 我想做一个小部件默认做的任何事情。就像我想看到first_btn 在我左键单击second_btn 时被推入和退出一样。
  • 所以您只是对按钮的relief 感到好奇吗?您可以在回调中控制它。另外,还有一个invoke 方法。
  • 有first_btn.event_generate('&lt;...&gt;')触发给定事件。
  • “动画行为”取决于事件,无论这些事件与哪些标签相关联。您可以轻松地 event_generate 一系列 &lt;Button-1&gt; 和 &lt;ButtonRelease-1&gt; 事件,在“动画”点击之间存在时间延迟。一个粗略的解释是,在 tk 的引擎盖下为这些事件设置动画,每个事件调用一个相关的函数(分别为 tkButtonDown 和 tkButtonUp)。因此,使用relief 在没有任何事件且没有任何“变通”的情况下为点击设置动画的唯一方法是直接调用tkButtonInvoke 函数(root.tk.call('::tk::ButtonInvoke', second_btn))。
  • 同样适用于所有小部件!例如,您可以看到Menu 和“Alt-keys”的交互如何绑定here(查找tk::TraverseToMenu 函数)。

标签: python tkinter binding tcl tk


【解决方案1】:

要调用绑定到给定序列的回调(例如&lt;Button-1&gt;),您可以使用widget.event_generate(&lt;sequence&gt;, **kwargs)。例如,对于 &lt;Button-1&gt; 事件,可选的关键字参数可以是 x=0、y=0。这将触发与序列关联的所有回调(无论它们是否与bind、bind_class 或bind_all 绑定都无关紧要)。

在下面的例子中,当第二个按钮被点击时,它会降低第一个按钮,就好像它也被点击了一样:

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()

但是,当从命令行以交互方式进行测试时,生成键盘事件通常不起作用,因为小部件没有键盘焦点。因此,使用以下代码,当单击按钮时,View 菜单将打开,就像我们完成了 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()

但是当我从 IPython QtConsole 执行 root.event_generate('&lt;Alt-v&gt;') 时,什么也没有发生。解决方法是在生成事件之前强制键盘焦点:

root.focus_force()
root.event_generate('<Alt-v>')

【讨论】:

  • 无论有没有focus_force,仍然无法使其工作(单击按钮时没有任何反应)。
  • @Nae 当我运行它时,带有菜单的代码段对我有用,菜单会以Alt-v 和当我单击按钮时打开。所以我不知道你的问题来自哪里。我不知道它是否相关,但我使用的是 linux 和 tk 8.6.7。
  • 我使用的是 Windows 7、python 3.6 和 tk 8.6。 Alt-v 打开菜单但按钮似乎没有做任何事情。我还尝试使用定义的函数调用这些函数并使用 lambda [,] 方式。
猜你喜欢
  • 1970-01-01
  • 2021-07-09
  • 1970-01-01
  • 1970-01-01
  • 2015-06-27
  • 1970-01-01
  • 2015-06-17
  • 2015-10-17
  • 1970-01-01
相关资源
最近更新 更多