1

I have built a simple UI using tKinter, Python 2.7. My code looks like this:

from Tkinter import * 
import Tkinter, Tkconstants, tkFileDialog, tkMessageBox

class FileZap():
    def __init__(self, root):
        root.title("Test_App")
        root.geometry("900x550")        

        self.menu = Menu(root)
        self.fileMenu = Menu(self.menu)
        self.funcMenu = Menu(self.menu)
        self.advMenu = Menu(self.menu)
        self.toolMenu = Menu(self.menu)

        root.config(menu=self.menu, width=500, relief=RAISED, borderwidth=2)

        self.menu.add_cascade(label="File", menu=self.fileMenu)
        self.menu.add_cascade(label="Functions", menu=self.funcMenu)
        self.menu.add_cascade(label="Advanced", menu=self.advMenu)
        self.menu.add_cascade(label="Tools", menu=self.toolMenu)
        self.menu.add_command(label="Quit", command=root.quit)

        self.fileMenu.add_command(label="New")
        self.fileMenu.add_command(label="Open")
        self.fileMenu.add_command(label="Quit", command=root.quit)


        self.funcMenu.add_command(label="Properties")
        self.funcMenu.add_command(label="Properties")
        self.funcMenu.add_command(label="Properties")
        self.funcMenu.add('separator')
        self.funcMenu.add_command(label="Properties")
        self.funcMenu.add_command(label="Properties")       



root = Tkinter.Tk()
file_zap = FileZap(root)
root.mainloop()

I am wondering if I can generate this with better code- specifically using a for loop (or multiple loops).

I tried declaring a list and attempting to iterate through it for some of this, so for example:

menuItems = ['File','Functions','Advanced','Tools','Quit']

for item in menuItems:
    self.menu.add_cascade(label=item, menu=self.fileMenu)

to replace this block:

self.menu.add_cascade(label="File", menu=self.fileMenu)
self.menu.add_cascade(label="Functions", menu=self.funcMenu)
self.menu.add_cascade(label="Advanced", menu=self.advMenu)
self.menu.add_cascade(label="Tools", menu=self.toolMenu)
self.menu.add_command(label="Quit", command=root.quit)

but this didn't work out and there is more to consider. I would be grateful if someone could show me a better way of doing this, so I may apply it to the rest of my UI. I have read that using lambda functions might be what I need to do, although again I'm not sure how...

1 Answer 1

2

You could use OrderedDict and as you said, run with a loop through the dictionary and add the key which is the label and the menu which is the value.

self.menuItems = OrderedDict([('File',self.fileMenu),('Functions',self.funcMenu),('Advanced',self.advMenu),('Tools', self.toolMenu),('Quit', root.quit)])

for k,v in self.menuItems.items():
    self.menu.add_cascade(label=k, menu=v)

Try to understand how those three line works and use their logic.

    for k,v in self.menuItems.items():
        self.menu.add_cascade(label=k, menu=v)

from Tkinter import *
import Tkinter, Tkconstants, tkFileDialog, tkMessageBox
from collections import OrderedDict

class FileZap():
    def __init__(self, root):
        root.title("Test_App")
        root.geometry("900x550")
        self.menu = Menu(root)
        self.fileMenu = Menu(self.menu)
        self.funcMenu = Menu(self.menu)
        self.advMenu = Menu(self.menu)
        self.toolMenu = Menu(self.menu)

        root.config(menu=self.menu, width=500, relief=RAISED, borderwidth=2)

        self.menuItems = OrderedDict([('File',self.fileMenu),('Functions',self.funcMenu),('Advanced',self.advMenu),('Tools', self.toolMenu),('Quit', root.quit)])

        for k,v in self.menuItems.items():
            self.menu.add_cascade(label=k, menu=v)

        self.commands = ["New", "Open", "Quit"]

        for comm in self.commands:
            if comm != "Quit":
                self.fileMenu.add_command(label=comm)
            else:
                self.fileMenu.add_command(label=comm, command=root.quit)

        for index in range(6):
            if index != 3:
                self.funcMenu.add_command(label="Properties")
            else:
                self.funcMenu.add('separator')

root = Tkinter.Tk()
file_zap = FileZap(root)
root.mainloop()
Sign up to request clarification or add additional context in comments.

1 Comment

ah this is great. I've looked at what you're doing here and it's making sense to me. I've not come across OrderedDict before, so something new to look at there. Thank you for this response, extremely helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.