Search code examples
pythontkintermenubar

Python Tkinter menu bars don't display


I'm trying to make a GUI using Tkinter and have come to implementing a menu bar. I've looked at a few tutorials and written some code for it, but a menu bar never seems to appear - just a blank frame with a white background. This doesn't just happen for my code though; on copying and pasting the code of one of the aforementioned tutorials into a new script, the same behaviour is exhibited.

I'd appreciate it if anyone could shed any light on what's causing this. My system is OS X 10.5, Python 2.7, Tk 8.4. Here's the code from the tutorial that doesn't appear to work:

#!/usr/local/bin/python2.7

from Tkinter import *
from ttk import *

class App(Frame):
    def __init__(self):
            Frame.__init__(self)

            self.master.geometry('400x300')
            self.master.title(__file__)

            self.pack()

            self.menu = Menu(tearoff=False)
            self.master.config(menu = self.menu)

            fm = self.file_menu = None
            fm = Menu(self.menu, tearoff=False)
            self.menu.add_cascade(label='File', menu = fm)

            fm.add_command(label='Say Hello', command = self.say_hello)
            fm.add_separator()
            fm.add_command(label='Quit', command = self.quit)

            self.mainloop()

    def say_hello(self, *e):
            self.label = Label(self.master, text='Hello there!')
            self.label.pack(anchor=CENTER, fill=NONE, expand=YES, side=LEFT)

if __name__ == '__main__':
    App()

and my code is here:

from Tkinter import *

class App(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)

        parent.title("Cluedo Solver 1.0")

        menubar = Menu(root)
        menubar.add_command(label="File")
        menubar.add_command(label="Quit", command=root.quit())

        root.config(menu=menubar)

root=Tk()
root.geometry("300x250+300+300")
app=App(root)
root.mainloop()

Solution

  • Code with Explanation

    From personal experience, I have found that it is usually easier to manage all widgets in a widgets method. That is what I did here, and it worked. Also, instead of parent, I used master. I will now walk you through the code step-by-step.

    from Tkinter import *
    

    We import Tkinter (GUI stuff)

    class App(Frame):
    

    We create a class called App, which is the Frame where widgets are held.

        def __init__(self, master):
            Frame.__init__(self, master)
            self.grid()
            self.widgets()
    

    We create a method called __init__. This initializes the class, and runs another method called widgets.

        def widgets(self):
    
    
            menubar = Menu(root)
            menubar.add_command(label="File")
            menubar.add_command(label="Quit", command=root.quit())
    
            root.config(menu=menubar)
    

    We create the widgets method. This is where the widget, menubar is added. If we were to create anymore widgets, they would also be here.

    root=Tk()
    root.title("Menubar")
    app=App(root)
    root.mainloop()
    

    Lastly, we give the entire window some properties. We give it a title, Menubar, and run the App class. lastly, we start the GUI's mainloop with root.mainloop.