将事件绑定到小部件元素和提供的有关事件的信息?

Binding events to widget elements and information provided about an event?

我对 Tcl/Tk 中提供的有关事件的信息有点困惑。

是否可以在 Tcl/Tk 中确定滚动条的哪个元素在 ButtonPress 事件的鼠标下方,例如 arrow1 或 slider?

此外,是否可以将事件绑定到滚动条的特定元素,例如v_scroll.arrow1

我知道滚动条内置了用于滚动的事件,但正在尝试确定事件的整体工作方式以及提供的有关它们的信息。

是否可以确定哪个小部件或小部件元素发生了任何鼠标事件,例如绑定到父项 window 并查询事件是在哪个子项上发起的?

看来 Python 有 event.widget 但我没有使用 Python 而是 Tcl。

我一直在阅读 Dr. Ousterhout 的书和文档,但不幸的是,没能找到它。

当然,我可以绑定到滚动条,并确定按下了哪个鼠标按钮,但不能确定滚动条的哪个元素当时在鼠标下方。仅使用 winfo returns 滚动条 .v_scroll 而不是鼠标下的元素。

谢谢。

ttk::scrollbar .v_scroll -orient vertical -command ".canvas yview"
bind .v_scroll <ButtonPress> { puts "Pressed button %b at [winfo containing %X %Y]" }

Is it possible in Tcl/Tk to determine which element of a scrollbar was under the mouse for a ButtonPress event, such as arrow1 or slider?

滚动条的 identify 方法正是这样做的:

set what [$scrollbar identify $x $y]

Also, is it possible to bind an event to a particular element of a scrollbar, such as v_scroll.arrow1?

没有。实际上,自己将任何东西绑定到滚动条通常不是一个好主意。 class 绑定可以满足您的需要,最好不要管它。滚动条滚动的小部件上的绑定更好。

Is it possible to determine which widget or widget element upon which any mouse event took place, such as binding to a parent window and querying upon which child an event was initiated?

是的。事件有一个 %W 替换,即作为它们目标的小部件(注意:只有 canvastext 小部件真正允许子小部件绑定)并且通常被传递给小部件及其顶层(主要用于关键加速器)。您可以通过调整传递小部件的 bindtags 来列出额外的目标,让其他小部件成为传递给小部件的事件的目标,但是您应该小心,因为如果小部件没有为此做好准备,这可能会非常混乱。 (根据我的经验,只有顶层、框架和画布是好的目标,主要是因为它们通过 class 绑定获得了很少的默认绑定。)许多应用程序根本不使用 bindtags,还有更多不要在绑定标签中放置额外的小部件;它非常微妙。有时,生成一个虚拟事件反而是一种更简洁的方法,但这对你来说是否正确在很大程度上取决于 both 大局 细节你想做什么。

您还可以在事件绑定中使用 winfo containing 来发现特定 全局 坐标下的小部件(%X %Y,而不是 %x %y).你通常不会这样做,除非你真的需要它;如果您正在进行拖放操作,这一点至关重要(因为按下鼠标按钮期间的用户交互事件始终会传送到开始按下鼠标的小部件)。可以使用抓取来修改它,但抓取是破坏应用程序(如果使用全局抓取甚至是登录会话!)的好方法,因此需要格外小心。

Widget 子组件标识始终 由widget 决定。按照惯例,这是小部件的 identify 方法的问题,但这只是惯例;画布和文本小部件使​​用不同的机制。并不是所有的小部件都有子组件;例如,classic buttons 不会(但 ttk::buttons 会)。通常,绑定脚本使用此类标识来决定下一步要做什么,而不会在其他任何地方使用。

综上所述,事件管理很复杂。在某些情况下,几乎所有的并发症都是必要的,幕后发生了很多事情。