2

Sample code:

package require Tk

menu .mymenu
. configure -menu .mymenu

puts [winfo children .]

Using Tcl 8.6, this prints out:

.mymenu .#mymenu

I'm confused where the .#mymenu identifier comes from.

Note that when using this same code on an explicitly created toplevel window (since . is the implicitly generated window in Tk), the results are different:

package require Tk

toplevel .win

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

puts [winfo children .win]

This prints:

.win.mymenu

This seems like the proper behavior. So why is the result different for the implicitly generated window in the first sample code?

Andrej Mitrović
  • 3,322
  • 3
  • 20
  • 33
  • Just pointing out that doing `.win configure -menu .mymenu` prints out `.win.mymenu .win.#mymenu`. – Jerry Aug 17 '13 at 18:35

1 Answers1

3

Quick answer: the menubar is actually a clone of the menu you specify, and that clone has that odd name.


For reasons I've never taken the time to entirely understand, menubars are cloned (with the clone method — never call that yourself!) off the menu that you specify; I believe it has something to do with allowing the same menu to be placed on multiple windows and ensuring correct nesting hierarchy, and the same mechanism is also used for torn-off menus (an interaction paradigm that's largely fallen out of favor these days). This clone shares virtually all its properties with the menu it was cloned from, but is its own widget. The clones are created with names derived from the source menu widget and the toplevel into which the clone is being inserted. If the target toplevel was .foo.bar and the menu passed to the -menu option was .grill.menu, then the clone will be .foo.bar.#grill#menu (the dots in the name of the menu become # characters); widget name construction near . is often slightly special.

You are advised to not poke too deeply in the menu cloning mechanism. Pretend that those strangely-named widgets don't exist. That works very well for nearly everything (and is more cross-platform portable too; menu mechanisms vary a lot between platforms). The only exception is if you are doing tooltips/status-bar display based on menu entries; the natural way of doing that feature (binding to the menu) ends up delivering the names of the clones to your callbacks. It's not hard to workaround, but you need to take care if you're doing this sort of thing.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • Great information, thanks. Actually I'm writing a language binding to Tk, and I have a mapping of all widget path names into the native language widget class object instances, however I was getting assertions from my part because I couldn't find a mapping to these objects (since they were not created from the bindings themselves but this internal clone method you mentioned now). Thanks for the heads up! – Andrej Mitrović Aug 17 '13 at 21:13