2

示例代码:

package require Tk

menu .mymenu
. configure -menu .mymenu

puts [winfo children .]

使用 Tcl 8.6,打印出来:

.mymenu .#mymenu

我很困惑.#mymenu标识符的来源。

请注意,当在显式创建的顶层窗口(因为.是 Tk 中隐式生成的窗口)上使用相同的代码时,结果会有所不同:

package require Tk

toplevel .win

menu .win.mymenu
. configure -menu .win.mymenu

puts [winfo children .win]

这打印:

.win.mymenu

这似乎是正确的行为。那么为什么第一个示例代码中隐式生成的窗口的结果不同呢?

4

1 回答 1

3

快速回答:菜单栏实际上是您指定的菜单的克隆,并且该克隆具有奇怪的名称。


由于我从未花时间完全理解的原因,菜单栏被克隆(使用clone方法 - 永远不要自己调用它!)您指定的菜单;我相信这与允许将相同的菜单放置在多个窗口上并确保正确的嵌套层次结构有关,并且相同的机制也用于撕下的菜单(这种交互范式如今已基本失宠)。这个克隆几乎与它被克隆的菜单共享它的所有属性,但它是它自己的小部件。克隆是使用从源菜单小部件和克隆插入的顶层派生的名称创建的。如果目标顶层是.foo.bar并且传递给-menu选项的菜单是.grill.menu,那么克隆将是.foo.bar.#grill#menu(菜单名称中的点变成#字符);附近的小部件名称构造.通常有点特殊。

建议您不要在菜单克隆机制上戳得太深。假装那些名字奇怪的小部件不存在。这对几乎所有东西都非常有效(并且更具有跨平台便携性;菜单机制在平台之间有很大差异)。唯一的例外是如果您正在根据菜单条目进行工具提示/状态栏显示;执行该功能(绑定到菜单)的自然方式最终将克隆的名称传递给您的回调。解决方法并不难,但如果你正在做这种事情,你需要小心。

于 2013-08-17T20:47:55.447 回答