''' lecture03_display_1_basic.py Demo of Tkinter module GUI features Oliver W. Layton CS251: Data Analysis and Visualization Spring 2019 Best site for Tkinter help: http://effbot.org/tkinterbook/ ''' # import tk import tkinter as tk class DisplayApp: '''Create a class to build and manage the display''' def __init__(self, width, height): # create a tk object, which is the root window self.root = tk.Tk() # width and height of the window self.initialWidth = width self.initialHeight = height # set up the geometry for the window. The +values are X and Y offsets. # Note: Y is positive going downward self.root.geometry(newGeometry=f'{self.initialWidth}x{self.initialHeight}+100+200') # set the title of the window self.root.title('My cool app!') # set the maximum size of the window for resizing self.root.minsize(width=300, height=300) self.root.maxsize(width=1600, height=1000) # Make menu bar items self.buildMenus() # Make the right-hand-side control center self.buildControls() # Make the canvas self.buildCanvas() # make keyboard buttons do stuff self.setBindings() # bring the window to the front (vs. lower()) self.root.lift() # self.root.lower() # - do idle events here to reliably get actual canvas size self.root.update_idletasks() # now we can ask the size of the canvas print(self.root.winfo_geometry()) def buildCanvas(self): '''Create a canvas object to draw stuff''' # expand: whether to expand the canvas when user resizes window # fill=tk.BOTH: expand canvas horizontal and vertically self.canvas = tk.Canvas(master=self.root, width=self.initialWidth, height=self.initialHeight) self.canvas.pack(expand=tk.YES, fill=tk.BOTH) def buildMenus(self): # Create a root menu object menu = tk.Menu(master=self.root) # Associate the menu with the app self.root.config(menu=menu) # create a File menu filemenu = tk.Menu(master=menu) menu.add_cascade(label='File', menu=filemenu) # Let's add some actual commands! filemenu.add_command(label='Quit Cmd+Q', command=self.handleQuit) filemenu.add_command(label='Clear Cmd+C', command=self.handleClear) # Make another menu called Command cmdMenu = tk.Menu(master=menu) menu.add_cascade(label='Command', menu=cmdMenu) # add some commands cmdMenu.add_command(label='Test1', command=self.handleNothing) cmdMenu.add_command(label='Test2', command=self.handleNothing) cmdMenu.add_separator() cmdMenu.add_command(label='Test3', command=self.handleNothing) # Menu inside 'Command' menu testMenu = tk.Menu(master=cmdMenu) cmdMenu.add_cascade(label='Test Menu', menu=testMenu) testMenu.add_command(label='Test4', command=self.handleNothing) def buildControls(self): # Right hand side panel inside the main app for controls (e.g. buttons) pane = tk.Frame(master=self.root) pane.pack(side=tk.RIGHT, fill=tk.Y) # visual divider between canvas and control frame sep = tk.Frame(master=self.root, height=self.initialHeight, width=4, borderwidth=3, relief=tk.RAISED) sep.pack(side=tk.RIGHT) # Text label on top label = tk.Label(master=pane, text='Control Panel', width=20) label.pack(side=tk.TOP) def setBindings(self): # Press CMD+Q to close the app self.root.bind('', self.handleQuit) def handleNothing(self, event=None): print('Doing nothing') def handleQuit(self, event=None): '''We want to call this method when the user quits the application''' print('Quitting the app...') self.root.destroy() def handleClear(self, event=None): '''We want to call this method when the user wants to clear plotted data''' print('Clearing the data...') pass def main(self): print('Entering main loop') # Draw a line on the canvas (x1, y1, x2, y2) self.myLine = self.canvas.create_line(100, 100, 300, 300) # Run main loop to listen for events self.root.mainloop() if __name__ == "__main__": dapp = DisplayApp(1200, 675) dapp.main()