关于在 Tcl/Tk 中构建事件的新手问题

Novice question about structuring events in Tcl/Tk

如果有人试图构建一个具有半复杂 GUI 的桌面程序,尤其是用户可以在其中打开相同 GUI 组件的多个实例的程序,例如具有“项目”GUI 并允许用户同时打开多个项目在主要 window 中,将事件侦听器进一步推向小部件层次结构并使用事件详细信息来确定事件发生在哪个小部件上,而不是将事件侦听器放置在每个单独的小部件上,这是一种很好的做法吗?

例如,在 Web 浏览器中执行类似操作时,任何单个项目 GUI 元素上都没有事件侦听器。侦听器位于包含每个项目 GUI 的多个实例的父容器上。一个项目在其 GUI 中有多个选项卡,但在一个项目中一次只能看到一个选项卡,并且在任何时候只能看到一个项目;因此,很容易在 HTML 元素上使用 类,然后在 event.target 上使用 e.matches() 方法来对当前可见项目中的当前可见选项卡进行操作一种与可见的项目无关的方式。在没有任何真正的性能测试的情况下,作为一个业余爱好者,我的不合格印象是尽可能少的事件监听器更有效,我通过阅读不是很准确的信息得到了大部分信息。

我最近在 John Ousterhout 的书中读到,Tk 应用程序可以有数百个事件处理程序,我想知道是否像上面描述的那样试图限制它们的数量真的会对 Tcl/Tk 产生任何影响。

我问这个问题的目的仅仅是为了更好地理解事件,以便正确地开始我的 Tcl/Tk 程序的编码,而不必重新编码一堆结构不良的事件监听器。我不想对上述书中写的任何内容提出异议,如果我愿意的话,我也不知道这样做。

感谢您提供的任何指导。

拥有数百个事件处理程序通常只是一个标志,表明可能会发送大量不同的事件。由于您通常(但不总是)尝试将绑定专门化为尽可能具体,因此实际的事件处理程序通常非常小,但可能会调用一个过程来完成这项工作。这在实践中往往效果很好。我自己,我的经验法则是,如果它不是一个简单的调用,那么我将放入一个辅助程序;以这种方式调试它们更容易。 (我的规则的主要例外是如果我想生成一个 break。)

您通常可以 bind 设置四个级别(加上 canvastext 的更多特定于小部件的级别):

  1. 单独的小部件。这是您最常使用的小部件。
  2. 小部件class。这主要由 Tk 使用;您通常 不想 更改它,因为它可能会改变您刚刚使用的代码的行为。 (例如,不要改变按钮的行为!)
  3. 包含小部件的顶层。这是热键的理想选择。 (不过要非常小心;这个级别的一些绑定可能会很麻烦。<Destroy> 是通常会咬人的那个。)顶层小部件本身没有这个,因为规则 1.
  4. all,说到做到,而且您几乎不需要。

您可以用 bindtags 定义其他人...但这通常不是一个好计划,因为它需要大量工作。

要记住的另一件事是 Tk 支持虚拟事件,<<FooBarHappened>>。它们有各种各样的用途,但复杂应用程序中的主要用途(您应该注意)是用于定义偶尔由一系列低级事件触发的高级事件,以及除鼻祖不妨留意一下。