Picking from a Menu!
Sometimes it's nice to have a menu to select things from. Right now, we can save only one file and load the same file in our program. It would be nice if we could load any picture file that we wanted and save to any file name we wanted. This can be done easily enough in Tkinter.
To begin, we'll import another module that will allow us to use dialog boxes later in the code.
import tkinter.filedialog
To create a menu in Tkinter, you first create a menu bar. This menu bar should be added right after the window is created. Then, the menu bar can have menu items added to it, like a "File" menu.
bar = tkinter.Menu(root) fileMenu = tkinter.Menu(bar,tearoff=0)
The next thing is to attach some menu items under the file menu. Each menu item is going to have a command associated with it. We'll create an "Open ..." menu item first.
def openFileHandler(): file = tkinter.filedialog.askopenfile(parent=root,\ mode='rb',initialdir='.',title='Choose a file') if file != None: try: filename = file.name file.close() clear() print("Opening File", file.name) xmldoc = minidom.parse(file.name) docroot = xmldoc.getElementsByTagName("Drawing")[0] pointElements = \ docroot.getElementsByTagName("Point") data["points"] = [] for pointElement in pointElements: if pointElement.firstChild.data == "True": penup = True else: penup = False color = pointElement.attributes["color"].value width = \ int(pointElement.attributes["width"].value) x = float(pointElement.attributes["x"].value) y = float(pointElement.attributes["y"].value) p = Point(x,y,color,width,penup) data["points"].append(p) for point in data["points"]: point.draw(t) screen.update() except: print("file not found") fileMenu.add_command(label="Open ...", \ command=openFileHandler)
To save a file, we'll add a "Save As ..." menu item.
def saveFileHandler(): file = tkinter.filedialog.asksaveasfilename( \ parent=root,initialfile="drawing.xml", \ initialdir=".",title='Choose a file name') if file != None: try: print("Saving File", file) file = open(file,"w") file.write( \ '<?xml version="1.0" encoding="UTF-8" standalone="no" ?>\n') file.write('<Drawing>\n') for i in range(len(data["points"])): file.write(str(data["points"][i])+'\n') file.write('</Drawing>\n') file.close() except: print("file not found") fileMenu.add_command(label="Save As ...", \ command=saveFileHandler)
We can also add an exit menu item to the File menu. Exiting is simple enough we don't have to write our own handler. The second line below adds our file menu to the menu bar as a cascading menu. A cascading menu is a menu that when clicked reveals its menu items.
fileMenu.add_command(label="Exit",command=root.quit) bar.add_cascade(label="File",menu=fileMenu) root.config(menu=bar)
That's about it! You now have a program that saves to a file of your choosing and loads files of your choosing. Hope you enjoyed the class. Hope to see you in a Computer Science class someday!
Try it Out!
You can add buttons to your program that contain a color. For instance, if you want to set the color to "red", then you could create a red button as follows. You first add a frame to put the colors in. This will help to make the color buttons group nicely, but you only do this part once.
colorFrame = tkinter.Frame(frame) colorFrame.pack()
Then, you can add each of your color buttons as follows.
def redHandler(): colorVar.set("Red") redButton = tkinter.Button(colorFrame,text="Red",\ bg="red",fg="red",command=redHandler) redButton.grid(row=1,column=1)
If you add more buttons, change the row and column that the buttons appear in to group them as you want. If you run this code on a Mac, the buttons will not have different colors because Macs don't support buttons of different colors in Tkinter.
If you get stuck, ask for help!