首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Tcl/Tk 8.6.11及更高版本中的<<MenuSelect>>

Tcl/Tk 8.6.11及更高版本中的<<MenuSelect>>
EN

Stack Overflow用户
提问于 2021-12-02 08:31:51
回答 2查看 57关注 0票数 0

我在Tcl/Tk 8.6.11 (在LinuxDebian10.7中试用过)中的MenuSelect事件有问题。

事实上,它根本不会为主菜单和撕下的菜单触发。虽然在Tcl/Tk 8.6.9中工作正常,甚至在8.6.11 -只有在菜单没有被撕下的情况下才能工作。

测试代码:

代码语言:javascript
复制
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 .]}]

我尝试了以下(虽然愚蠢)替换方法:

代码语言:javascript
复制
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寻找任何提示。

EN

回答 2

Stack Overflow用户

发布于 2021-12-04 16:17:09

这可能与菜单使用克隆来删除和菜单栏有关。从documentation

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

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

通常,最好的做法是避免使用<<MenuSelect>>,而只在可以选择的条目上设置-command (或者只为checkbuttonradiobutton条目设置正确的模型变量)。完全避免撕扯;它们是一种菜单交互的风格,在25年前就已经过时了。

票数 0
EN

Stack Overflow用户

发布于 2021-12-05 12:24:47

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

例如,我们有类似这样的东西:

代码语言:javascript
复制
bind Menu <<MenuSelect>> [list ::somehandler %W]

如果菜单项在克隆菜单中,%W通配符将作为“克隆”名称传递给::name处理程序。

和::某个处理者应该计算出谁是现实中的%W。

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

这是它的一个稍微修改过的版本:

代码语言:javascript
复制
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 of:

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

感谢Donal和Csaba的提示。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70196251

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档