示例代码:
package require Tk
menu .mymenu
. configure -menu .mymenu
puts [winfo children .]
使用Tcl 8.6,打印出来:
.mymenu .#mymenu
我很困惑.#mymenu
标识符的来源。
请注意,在显式创建的toplevel窗口上使用相同的代码时(因为.
是Tk中隐式生成的窗口),结果是不同的:
package require Tk
toplevel .win
menu .win.mymenu
. configure -menu .win.mymenu
puts [winfo children .win]
打印:
.win.mymenu
这似乎是正确的行为。那么为什么第一个示例代码中隐式生成的窗口的结果不同?
答案 0 :(得分:3)
快速回答:菜单栏实际上是您指定的菜单的克隆,并且该克隆具有奇怪的名称。
由于我从未花时间完全理解的原因,菜单会被克隆(使用clone
方法 - 永远不要自己调用!)在您指定的菜单之外;我认为它与允许将相同的菜单放在多个窗口上并确保正确的嵌套层次结构有关,并且相同的机制也用于撕掉的菜单(这些日子基本上不受欢迎的交互范例)。这个克隆几乎与其克隆的菜单共享其所有属性,但它是自己的小部件。使用从源菜单小部件和要插入克隆的顶层派生的名称创建克隆。如果目标顶层为.foo.bar
且传递给-menu
选项的菜单为.grill.menu
,则克隆将为.foo.bar.#grill#menu
(菜单名称中的点变为{ {1}}个字符); <{1}}附近的小部件名称构造通常略显特殊。
建议您不要在菜单克隆机制中过分深入。假装那些奇怪命名的小部件不存在。几乎所有东西都能很好地工作(并且更加跨平台便携;菜单机制在平台之间变化很大)。唯一的例外是如果您正在根据菜单条目进行工具提示/状态栏显示;执行该功能的自然方式(绑定到菜单)最终会将克隆的名称传递给回调。解决方法并不难,但如果你正在做这类事情,你需要小心。