1"""A directory browser using Ttk Treeview. 2 3Based on the demo found in Tk 8.5 library/demos/browse 4""" 5import os 6import glob 7import Tkinter 8import ttk 9 10def populate_tree(tree, node): 11 if tree.set(node, "type") != 'directory': 12 return 13 14 path = tree.set(node, "fullpath") 15 tree.delete(*tree.get_children(node)) 16 17 parent = tree.parent(node) 18 special_dirs = [] if parent else glob.glob('.') + glob.glob('..') 19 20 for p in special_dirs + os.listdir(path): 21 ptype = None 22 p = os.path.join(path, p).replace('\\', '/') 23 if os.path.isdir(p): ptype = "directory" 24 elif os.path.isfile(p): ptype = "file" 25 26 fname = os.path.split(p)[1] 27 id = tree.insert(node, "end", text=fname, values=[p, ptype]) 28 29 if ptype == 'directory': 30 if fname not in ('.', '..'): 31 tree.insert(id, 0, text="dummy") 32 tree.item(id, text=fname) 33 elif ptype == 'file': 34 size = os.stat(p).st_size 35 tree.set(id, "size", "%d bytes" % size) 36 37 38def populate_roots(tree): 39 dir = os.path.abspath('.').replace('\\', '/') 40 node = tree.insert('', 'end', text=dir, values=[dir, "directory"]) 41 populate_tree(tree, node) 42 43def update_tree(event): 44 tree = event.widget 45 populate_tree(tree, tree.focus()) 46 47def change_dir(event): 48 tree = event.widget 49 node = tree.focus() 50 if tree.parent(node): 51 path = os.path.abspath(tree.set(node, "fullpath")) 52 if os.path.isdir(path): 53 os.chdir(path) 54 tree.delete(tree.get_children('')) 55 populate_roots(tree) 56 57def autoscroll(sbar, first, last): 58 """Hide and show scrollbar as needed.""" 59 first, last = float(first), float(last) 60 if first <= 0 and last >= 1: 61 sbar.grid_remove() 62 else: 63 sbar.grid() 64 sbar.set(first, last) 65 66root = Tkinter.Tk() 67 68vsb = ttk.Scrollbar(orient="vertical") 69hsb = ttk.Scrollbar(orient="horizontal") 70 71tree = ttk.Treeview(columns=("fullpath", "type", "size"), 72 displaycolumns="size", yscrollcommand=lambda f, l: autoscroll(vsb, f, l), 73 xscrollcommand=lambda f, l:autoscroll(hsb, f, l)) 74 75vsb['command'] = tree.yview 76hsb['command'] = tree.xview 77 78tree.heading("#0", text="Directory Structure", anchor='w') 79tree.heading("size", text="File Size", anchor='w') 80tree.column("size", stretch=0, width=100) 81 82populate_roots(tree) 83tree.bind('<<TreeviewOpen>>', update_tree) 84tree.bind('<Double-Button-1>', change_dir) 85 86# Arrange the tree and its scrollbars in the toplevel 87tree.grid(column=0, row=0, sticky='nswe') 88vsb.grid(column=1, row=0, sticky='ns') 89hsb.grid(column=0, row=1, sticky='ew') 90root.grid_columnconfigure(0, weight=1) 91root.grid_rowconfigure(0, weight=1) 92 93root.mainloop() 94