#!/usr/bin/python ###################################################################### # listdir.py from Chun's Core Python Programming, # with annotated comments for explaining Tkinter ###################################################################### import os from time import sleep from Tkinter import * import pdb class DirList: ''' DirList is a simple GUI application that allows for the browsing of directory contents. ''' def __init__(self, initdir=None): pdb.set_trace() # Create a new Tk window self.top = Tk() # Label is a widget to display one or more lines of text # The constructor for a widget creates it in the window. # Each widget constructor can take an optional master and options. # In this case self.top, the root window is the master, and text is # one of the avaiable options for Label self.label = Label(self.top, text='Directory Lister' + ' v1.1') # packing resizes the widget to fit the text self.label.pack() # StringVar is a variable container to hold a string # It'll be used by some widgets and can also trigger callbacks self.cwd=StringVar(self.top) # Label for cwd self.dirl = Label(self.top, fg='blue', font=('Helvetica', 12, 'bold')) self.dirl.pack() # Frame is a container widget to hold and group other widgets self.dirfm = Frame(self.top) # Scrollbar is constructed with dirfm as its master. self.dirsb = Scrollbar(self.dirfm) # packing can take options too to determine the widget's # relative placement in the master. fill resizes the widget if # it's master grows self.dirsb.pack(side=RIGHT, fill=Y) # Listbox displays a list of selectable alternatives self.dirs = Listbox(self.dirfm, height=15, width=50, yscrollcommand=self.dirsb.set) # binding sets up a callback for a UI event. # this binds a double-click of the first mouse button # to the setdirandgo method # see below for more information about events self.dirs.bind('', self.setdirandgo) # config changes widget options after it was created self.dirsb.config(command=self.dirs.yview) self.dirs.pack(side=LEFT, fill=BOTH) self.dirfm.pack() # Entry takes one line of text as input # The textvariable is the StringVar above, which will update # the text displayed if it is changed self.dirn = Entry(self.top, width=50, textvariable=self.cwd) # bind the Return key to the dols callback self.dirn.bind('', self.dols) self.dirn.pack() # Frame for orgainzing command buttons self.bfm = Frame(self.top) # Buttons have an associated command callback when activated # No need to explicitly bind any mouse click events for a button self.clr = Button(self.bfm, text='Clear', command=self.clrdir, activeforeground='white', activebackground='blue') self.ls = Button(self.bfm, text='List Directory', command=self.dols, activeforeground='white', activebackground='green') self.quit = Button(self.bfm, text='Quit', command=self.top.quit, activeforeground='white', activebackground='red') self.clr.pack(side=LEFT) self.ls.pack(side=LEFT) self.quit.pack(side=LEFT) self.bfm.pack() if initdir: self.cwd.set(os.curdir) self.dols() # Callback functions are called after an event occurs. # An event is passed to the callback function with detail about the # event such as the widget generating the event, mouse position, # or keycode. # Callback for clearing the current directory entry def clrdir(self, ev=None): self.cwd.set('') # Callback for selection of a directory in the listing def setdirandgo(self, ev=None): self.last = self.cwd.get() self.dirs.config(selectbackground='red') check = self.dirs.get(self.dirs.curselection()) if not check: check = os.curdir self.cwd.set(check) self.dols() # Callback for a directory listing of a new directory def dols(self, ev=None): error = '' tdir = self.cwd.get() if not tdir: tdir = os.curdir if not os.path.exists(tdir): error = tdir + ': no such file' elif not os.path.isdir(tdir): error = tdir + ': not a directory' if error: self.cwd.set(error) # update() redraws the display element self.top.update() sleep(2) if not (hasattr(self, 'last') and self.last): self.last = os.curdir self.cwd.set(self.last) self.dirs.config(selectbackground='LightSkyBlue') self.top.update() return self.cwd.set('FETCHING DIRECTORY CONTENTS...') self.top.update() dirlist = os.listdir(tdir) dirlist.sort() os.chdir(tdir) self.dirl.config(text=os.getcwd()) self.dirs.delete(0, END) self.dirs.insert(END, os.curdir) self.dirs.insert(END, os.pardir) for eachFile in dirlist: self.dirs.insert(END, eachFile) self.cwd.set(os.curdir) self.dirs.config(selectbackground='LightSkyBlue') def main(): d = DirList(os.curdir) # mainloop starts the Tkinter event loop to receive and signal events mainloop() if __name__ == '__main__': main() # Tkinter is uses Tk widgets to create GUI elements for your python program # # Tk is a widget toolkit, created with the scripting language Tcl by # John K. Ousterhout, a early proponent of scripting languages. # # Widgets are reusable graphical UI elemenents. You see them all the # time when working with a UI. Buttons, menus, and scrollbars are all # widgets, as well as the windows and text areas in GUI applications. # # Widgets are automatically placed in the last containing frame or # windows unless given a different master. The layout placement is # controlled with options to pack() or grid() (which isn't used in # this example). Frames can be nested within other frames or windows # for organizing collections of widgets, like buttons in a toolbar. # # Programs written using Tkinter follow a callback event model, where # functions are called in response to some program or user generated # event. No threading is needed to catch and signal UI events. # # Events from the UI in Tkinter are represented in a special syntax # of the form , but there are abbreviated names # for many common events. Here are some of them # - is a left mouse button press, # use 2 for the middle button and 3 for the right button # - <1> is the same thing as above # - is a double click of the left mouse button # - the Enter key was pressed # - "a" responds when an "a" is typed on the keyboard #