0

我在 Tcl/Tk 8.6.11 中遇到了 MenuSelect 事件的问题(在 Linux、Debian 10.7 中尝试过)。

事实上,它根本不会触发主菜单和可撕下的菜单。尽管在 Tcl/Tk 8.6.9 甚至在 8.6.11 中都可以正常工作——只是在菜单没有被撕掉的情况下。

一个测试代码:

package require Tk
proc ::somehandler {w wt} {
  puts "Step [incr ::step]: $w / $wt, index=[$wt index active]"
}
set w [menu .m -tearoff 1]
$w add command -label {Item 1}
$w add command -label {Item 2}
bind $w <<MenuSelect>> [list ::somehandler $w %W]
pack [button .b -text "Click me" \
  -command {tk_popup .m [winfo pointerx .] [winfo pointery .]}]

我尝试了以下(虽然是愚蠢的)替换:

event delete <<MenuSelect>>
event add <<MenuSelect>> <Motion>
bind $w <<MenuSelect>> [list ::somehandler $w %W]

......结果相同。

看起来,它与 Tk 中处理的菜单路径有关,有点棘手,如上例所示。

我懒得在从 8.6.9 切换到 8.6.11/12、8.7 等时更改标准代码。

TIA 的任何提示。

4

2 回答 2

0

这可能与菜单使用克隆进行撕裂和菜单栏的事实有关。从文档中:

当一个菜单被设置为顶层窗口的菜单栏时,或者当一个菜单被撕掉时,就会产生一个菜单的克隆。这个克隆本身就是一个菜单部件,但它是原始部件的子部件。原始配置的更改会反映在克隆中。此外,任何指向的级联也会被克隆,以便菜单遍历正常工作。当撕下或菜单栏消失或原始菜单被破坏时,克隆将被破坏。

我不记得克隆到底是如何命名的,但您通常不会直接与它们交互;只有通过事件处理才能真正看到它们。(在为菜单做工具提示时,我只需要处理它们。)

通常,最好避免使用<<MenuSelect>>,而只是-command在可以选择的条目上设置 a (或者只为checkbuttonradiobutton条目设置模型变量)。并完全避免撕裂;它们是 25 年前过时的菜单交互方式。

于 2021-12-04T16:17:08.703 回答
0

对于 Tk 8.6.11+,应该使用bind Menu而不是bind $w(对于单个菜单项)。它向事件处理程序添加了一些杂技,该处理程序应该计算要处理的菜单项。

即我们有类似的东西:

bind Menu <<MenuSelect>> [list ::somehandler %W]

如果菜单项在克隆菜单中,则 %W 通配符作为“克隆”名称传递给::somehandler 。

::somehandler 应该计算出谁是现实中的 %W。

Csaba Nemethi 建议使用类似clonename的过程(来自 BWidget 包的 utils.tcl)。此过程从“普通”菜单项的路径中获取克隆名称。

这是它的一些修改版本:

proc clonename {mnu} {
  # Gets a clone name of a menu.
  #   mnu - the menu's path
  # This procedure is borrowed from BWidget's utils.tcl.

  set path [set menupath {}]
  set found 0
  foreach widget [lrange [split $mnu .] 1 end] {
    if {$found || [winfo class "$path.$widget"] eq {Menu}} {
      set found 1
      append menupath # $widget
      append path . $menupath
    } else {
      append menupath # $widget
      append path . $widget
    }
  }
  return $path
}

作为使用示例,请参见test.tcl的:

http://chiselapp.com/user/aplsimple/repository/baltip/zip/trunk/baltip.zip

感谢 Donal 和 Csaba 的提示。

于 2021-12-05T12:24:47.027 回答