100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Menus and Dialogs in Tk

Building application menu bars and menus with the menu widget, plus using Tk's standard dialog commands for messages, files, and colors.

Tk GUI BasicsIntermediate9 min readJul 10, 2026
Analogies

Building a Menu Bar

A Tk application's menu bar is built from menu widgets: you create a top-level menu with menu .menubar, attach it to the window using . configure -menu .menubar, and then populate it with cascading submenus—menu .menubar.file followed by .menubar add cascade -label File -menu .menubar.file—so the menu bar itself contains only cascades, while each cascade menu holds the actual clickable entries. Entries within a menu are added with add command -label "Open..." -command openFile -accelerator "Ctrl+O", where -accelerator only displays the shortcut text next to the label and does not itself bind the key—you still need a separate bind . <Control-o> openFile for the shortcut to actually work—and add separator inserts a thin dividing line to visually group related entries, such as separating Save and Save As... from Exit.

🏏

Cricket analogy: A menu bar containing only cascades that expand into real entries is like a match scorecard's top-level tabs—Batting, Bowling, Fielding—each of which expands to the actual detailed stats when selected, rather than showing every stat flatly on one screen.

tcl
menu .menubar
. configure -menu .menubar

menu .menubar.file -tearoff 0
.menubar add cascade -label "File" -menu .menubar.file
.menubar.file add command -label "Open..." -command openFile -accelerator "Ctrl+O"
.menubar.file add command -label "Save" -command saveFile -accelerator "Ctrl+S"
.menubar.file add separator
.menubar.file add command -label "Exit" -command {destroy .}

bind . <Control-o> openFile
bind . <Control-s> saveFile

Checkbutton and Radiobutton Menu Entries

Menu entries aren't limited to plain commands: add checkbutton -label "Word Wrap" -variable wrapVar -onvalue 1 -offvalue 0 puts a toggleable checkmark entry in the menu that stays synced to a Tcl variable exactly like a checkbutton widget does, and add radiobutton -label "12pt" -variable fontSizeVar -value 12 lets several radiobutton entries share one variable so only one can be checked at a time, useful for a font-size or view-mode submenu. Submenus are just cascades pointing at another menu widget, so a deeply nested structure like View > Zoom > 100% is built by creating .menubar.view, then .menubar.view.zoom, then adding add cascade -label Zoom -menu .menubar.view.zoom inside the view menu, and finally adding the individual zoom-level radiobutton entries inside the zoom menu itself.

🏏

Cricket analogy: Radiobutton menu entries sharing one variable, where selecting 12pt deselects 10pt, is like a broadcaster's single preferred-camera-angle setting where choosing the bowler's-end camera automatically deselects the square-leg camera option.

Passing -tearoff 0 when creating a menu (as in menu .menubar.file -tearoff 0) removes the dashed tear-off line that some platforms show at the top of a menu by default, which historically let users detach a menu into its own floating window. Most modern applications disable tear-off menus since the feature is rarely used and looks dated.

Context Menus and Popups

Context menus—the menu that appears on a right-click—are built the same way as a menu bar's submenus, as a standalone menu widget that isn't attached to any cascade, and are shown on demand with tk_popup .contextMenu $x $y, which posts the menu at the given screen coordinates and handles all the platform-specific details of positioning and dismissing it. The typical pattern binds the right mouse button (<Button-3> on Windows/Linux, though it's <Button-2> on some older Mac configurations, which is why cross-platform code often binds both) to a small procedure that calls tk_popup .contextMenu %X %Y, using the uppercase %X/%Y substitutions for screen-relative coordinates rather than the lowercase %x/%y, which are relative to the widget instead and would position the popup incorrectly.

🏏

Cricket analogy: tk_popup posting a menu at an exact screen coordinate on demand is like a broadcast graphics operator triggering a stats overlay to appear at a precise spot on screen only when a specific replay moment calls for it, not as a permanent fixture.

Standard Dialogs

Tk ships several ready-made modal dialogs so you don't have to hand-build common interactions: tk_messageBox -message "Delete this file?" -type yesno -icon warning shows a message with standard buttons and returns which button was pressed (yes or no) as its result; tk_getOpenFile and tk_getSaveFile show the platform's native file-picker and return the chosen path (or an empty string if canceled); and tk_chooseColor shows a color picker and returns the selected color as a hex string like #3a7bd5. Because these are modal dialogs, the Tcl script calling them blocks at that line until the user responds—the dialog commands don't return until the dialog is dismissed—which is exactly the behavior you want for a confirmation prompt, since the calling code typically needs the user's answer immediately before deciding whether to proceed with deleting the file or discarding the changes.

🏏

Cricket analogy: A modal tk_messageBox blocking execution until answered is like the third umpire's review process pausing play entirely—no more deliveries are bowled until the on-field decision is confirmed or overturned.

tk_messageBox, tk_getOpenFile, tk_getSaveFile, and tk_chooseColor are all modal and platform-native, meaning their exact visual appearance differs between Windows, macOS, and Linux and cannot be restyled with ttk themes. If you need a dialog with custom widgets or a non-native look, build it yourself as a toplevel window with grab set to make it modal, rather than trying to reskin these standard commands.

  • A menu bar is a menu widget attached to a toplevel with configure -menu; cascades link submenus, and add command/checkbutton/radiobutton/separator populate entries.
  • -accelerator only displays shortcut text; the actual key combination must be bound separately with bind.
  • add checkbutton and add radiobutton menu entries sync to a Tcl variable exactly like their standalone widget counterparts.
  • -tearoff 0 removes the dated tear-off dashed line from a menu.
  • Context menus are standalone menu widgets shown on demand with tk_popup .menu %X %Y, using screen-relative uppercase coordinates.
  • tk_messageBox, tk_getOpenFile, tk_getSaveFile, and tk_chooseColor are built-in modal, platform-native dialogs that block until the user responds.
  • Custom-styled modal dialogs must be hand-built as a toplevel with grab set, since the standard dialog commands can't be restyled.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#TclTkStudyNotes#MenusAndDialogsInTk#Menus#Dialogs#Building#Menu#StudyNotes#SkillVeris#ExamPrep