Dorian Dore
Dorian Dore

Reputation: 962

TkInter Menubar causes program to not run

I am trying to write a simple text editor using TkInter. I want it to have a menu bar like other text editors, where you can save, open another file, etc.

However, whenever I try to add a menu bar to my class, the program simply starts, hangs for about half a second, then exits. I have no idea why this is happening, or how to debug it. Here is my code.

#!/usr/bin/env python3

import functools
from tkinter import *

class mainWindow(Tk):
    def initiate(self):
        menuBarFrame = Frame(self).pack(side=TOP)
        menubar = Menu(menuBarFrame)
        menubar.add_command(label='Exit', command=quit())
        root.config(menu=menubar)
        mainloop()

win = mainWindow().initiate()

I tried adding .pack() to the line

menubar = Menu(menuBarFrame)

but it gives me the following traceback:

  File "XML.py", line 14, in <module>
    win = mainWindow().initiate()
  File "XML.py", line 9, in initiate
    menubar = Menu(menuBarFrame).pack()
  File "/usr/lib/python3.4/tkinter/__init__.py", line 1977, in pack_configure
    + self._options(cnf, kw))
_tkinter.TclError: can't pack ".140664986043280": it's a top-level window

When I remove the code for the menubar, and just replace it with a simple button, the application works and starts fine. What could be causing the problem?

Upvotes: 0

Views: 391

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 385970

The menu needs to be a child of the root window, rather than a child of a frame. You don't need MenuBarFrame at all.

Also, take a look at this line:

menubar.add_command(label='Exit', command=quit())

You are instructing Tkinter to immediately call the quit() function, and assign the result to the command attribute of the menu command. I'm guessing that quit() actually quits rather than returning a reference to some other function. You need to change it to this:

menubar.add_command(label='Exit', command=quit)

Of course, the other glaring problem is that you don't actually define root anywhere.

You definitely don't want to call pack() on the instance of Menu. The correct way to attach the menu to the window is with root.config(menu=menubar), like you're already doing.

Upvotes: 1

Related Questions