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

时间:2021-06-30 00:28:00

标签: tcl tk

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

是否可以在 Tcl/Tk 中确定滚动条的哪个元素在 ButtonPress 事件(例如箭头 1 或滑块)下位于鼠标下方?

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

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

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

似乎 Python 有 event.widget,但我使用的不是 Python,而是 Tcl。

我一直在阅读 Ousterhout 博士的书和文档,但很遗憾,一直找不到。

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

谢谢。

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

1 个答案:

答案 0 :(得分:1)

<块引用>

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

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

set what [$scrollbar identify $x $y]
<块引用>

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

没有。实际上,自己将任何内容绑定到滚动条通常不是一个好主意;类绑定可以满足您的需求,最好不要理会。滚动条滚动的小部件上的绑定更好。

<块引用>

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

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

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

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

总而言之,事件管理很复杂。在某些情况下,几乎所有的复杂性都是必要的,而且幕后还有很多事情要做。