I am going through the Tk/Tkinter tutorial and
when I try to run the menubar program I get two windows instead of a menubar on one window.

Here is the code:

from tkinter import *
from tkinter import ttk
root = Tk()
root.option_add('*tearOff', FALSE)

win = Toplevel(root)
menubar = Menu(win)
win['menu'] = menubar

menubar = Menu(win)
menu_file = Menu(menubar)
menu_edit = Menu(menubar)
menubar.add_cascade(menu=menu_file, label='File')
menubar.add_cascade(menu=menu_edit, label='Edit')

menu_file.add_command(label='New', command=None)
menu_file.add_command(label='Open...', command=None)
menu_file.add_command(label='Close', command=None)

root.mainloop()

Please let me know what I am doing wrong.

- WolfShield

Dani AI

Generated

Short answer: you created two windows. root = Tk() makes the main application window; Toplevel(root) makes a second one. That is why you saw two separate windows instead of a single window with a menu. There is a second bug too: the original code makes two different Menu objects (the first gets attached, then you overwrite the menubar variable with a new menu and populate the new one but never attach it).

was on the right track: keep it simple and attach a single menu to the window you actually want to use. If you really want only a Toplevel shown, hide the initial Tk() window with root.withdraw() and then attach the menu to the Toplevel. If you want the normal single-window app, just use the Tk() window and do not create a Toplevel.

Example (showing the hide-root pattern and avoiding the double-Menu mistake):

from tkinter import Tk, Toplevel, Menu

root = Tk()
root.withdraw()               # hide the automatic root window

win = Toplevel(root)
menubar = Menu(win, tearoff=0)
win.config(menu=menubar)

file_menu = Menu(menubar, tearoff=0)
menubar.add_cascade(label="File", menu=file_menu)
file_menu.add_command(label="Exit", command=win.destroy)

root.mainloop()

Troubleshooting checklist:

  • Decide whether to use Tk() (main window) or a Toplevel() (secondary window). Do not create both unless you intend two windows.
  • Create one menubar object and attach it with window.config(menu=menubar) (or window['menu']=...), then add submenus to that menubar.
  • Use tearoff=0 or root.option_add('*tearOff', FALSE) to disable silly tear-off menus.
  • On macOS the menu may appear in the system menu bar (that is expected).

If something still looks wrong, confirm which window is visible (root vs Toplevel) and that the Menu you populated is the same object you attached. is right: experimenting with small examples helps these layout/parenting rules sink in.

Recommended Answers

All 6 Replies

Too much junk in the code, try it this way ...

from tkinter import *
from tkinter import ttk

root = Tk()
root.option_add('*tearOff', FALSE)

menubar = Menu(root)
root.config(menu=menubar)
menu_file = Menu(menubar)
menu_edit = Menu(menubar)
menubar.add_cascade(menu=menu_file, label='File')
menubar.add_cascade(menu=menu_edit, label='Edit')

menu_file.add_command(label='New', command=None)
menu_file.add_command(label='Open...', command=None)
menu_file.add_command(label='Close', command=None)

root.mainloop()

There are some pretty bad tutorials floating about, which one is this exactly?

I am going through this one: http://www.tkdocs.com/tutorial/

What one would you suggest?

Thank you vegaseat, my program is working right now. Was it the 'Toplevel' that was
creating the second window?

- WolfShield

Just experiment with it!

This is sort of the Bible of Tkinter:
http://infohost.nmt.edu/tcc/help/pubs/tkinter.pdf

However bummer, you have to come up with your own examples and again experiment.

Thanks everyone!

- WolfShield

GUI programming takes a while to get used to. I always hang up on the widget layouts.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.