aboutsummaryrefslogtreecommitdiffstats
path: root/tkFileBrowser.py
diff options
context:
space:
mode:
Diffstat (limited to 'tkFileBrowser.py')
-rw-r--r--tkFileBrowser.py98
1 files changed, 75 insertions, 23 deletions
diff --git a/tkFileBrowser.py b/tkFileBrowser.py
index 3f18d19..a98c2fe 100644
--- a/tkFileBrowser.py
+++ b/tkFileBrowser.py
@@ -9,9 +9,11 @@ import win32ui
import win32gui
import os
+#TODO: refresh tree
+
class TkFileBrowser(tk.Frame):
- open = ""
+ _open = []
def __init__(self, parent, command, refresh = 20, types = [], showhidden = False):
"""Widget for browsing a windows filesystem.
@@ -38,14 +40,32 @@ class TkFileBrowser(tk.Frame):
self._book.pack(fill = tk.BOTH, expand = True)
self.after(self._refresh, self.refresh)
- def open_to(self, path):
+ def see(self, path):
"""Open the tree and book to this folder
Arguments:
path {str} -- path to open to
"""
- #TODO: make this function
- raise NotImplementedError
+ #open the correct book tab
+ split = path.replace("\\", "/").split("/")
+
+ #if requested is file, go to the folder in which it's in
+ if os.path.isfile(path):
+ del split[-1]
+
+ drive = split[0] + "\\"
+ self._book.select(self._book._get_drives().index(drive))
+
+ try:
+ self._book._tabs[drive]._tree.see("\\".join(split))
+ except tk.TclError:
+ #the node probably isn't loaded yet so we have to make it load before
+ #using .see()
+ for i in range(len(split) - 1):
+ self._book._tabs[drive]._populate_path("\\".join(split[:i+2]))
+ self._book._tabs[drive]._tree.item("\\".join(split[:i+2]), open = True)
+
+ self._book._tabs[drive]._tree.see("\\".join(split))
def refresh(self):
@@ -102,8 +122,9 @@ class TkFileBrowser(tk.Frame):
class DriveBook(ttk.Notebook):
- foldericons = {}
- fileicons = {}
+ _foldericons = {}
+ _fileicons = {}
+ _tabs = {}
def __init__(self, parent):
ttk.Notebook.__init__(self)
@@ -114,10 +135,11 @@ class DriveBook(ttk.Notebook):
def _draw_tabs(self):
self._drive_icons = self._get_icons() #store to attribute so it doesn't get removed by garbage deletion
for drive in self._drive_icons:
+ self._tabs[drive[0]] = FileTree(self, drive[0])
if os.path.split(drive[0])[1] != "":
- self.add(FileTree(self, drive[0]), text = "Home", image = drive[1], compound = tk.LEFT)
+ self.add(self._tabs[drive[0]], text = "Home", image = drive[1], compound = tk.LEFT)
else:
- self.add(FileTree(self, drive[0]), text = drive[0], image = drive[1], compound = tk.LEFT)
+ self.add(self._tabs[drive[0]], text = drive[0], image = drive[1], compound = tk.LEFT)
def _refresh(self):
"""Checks if a drive as been added or removed. If it has, tabs are refreshed.
@@ -169,10 +191,17 @@ class FileTree(tk.Frame):
def _on_click(self, event):
id = os.path.normpath(self._tree.focus())
+ print(id)
if os.path.isfile(id):
self._command(id)
else:
- self._populate_path(id)
+ try:
+ self._populate_path(id)
+ except tk.TclError:
+ #this node has already been opened, so delete children and load again
+ for child in self._tree.get_children(id):
+ self._tree.delete(child)
+ self._populate_path(id)
def _get_size(self, path):
"""Returns the size of a file. From:
@@ -199,46 +228,61 @@ class FileTree(tk.Frame):
return ('{} bytes').format(size)
def _populate_path(self, path):
- print("path:", path)
- if path in self._parent._get_drives():
+ #if the tree is blank, write to the root
+ if self._tree.get_children() == ():
node = ""
else:
node = path
folders, files = self._get_dirs_in_path(path)
- print("node:", node)
for folder in folders:
fullpath = os.path.join(path, folder)
- print("fullpath:", fullpath)
self._tree.insert(
parent = node,
index = tk.END,
iid = fullpath,
tag = fullpath,
text = folder,
- image = self._parent.foldericons[fullpath],
+ image = self._parent._foldericons[fullpath],
values = [folder, "", ""])
+ #setup a dummy so the '+' appears before it's loaded. Child stuff will be loaded when the user
+ #clicks on the plus
self._tree.insert(parent = fullpath, index = tk.END, tag = "dummy", text = "No avaliable files")
for file in files:
fullpath = os.path.join(path, file)
name, type_ = os.path.splitext(file)
+ #if the type is a shortcut, get the whole path as a key
+ if type_ == ".lnk" or type_ == ".exe":
+ icon = self._parent._fileicons[fullpath]
+ else:
+ icon = self._parent._fileicons[type_]
self._tree.insert(
parent = node,
index = tk.END,
iid = fullpath,
tag = fullpath,
text = file,
- image = self._parent.fileicons[type_],
+ image = icon,
values = [file, "", self._get_size(fullpath)])
+ #if there is more than one child, delete every child that isn't a path
+ #and hence delete the dummy
+ children = self._tree.get_children(node)
+ if len(children) > 1:
+ for child in children:
+ if not os.path.exists(child):
+ self._tree.delete(child)
+
def _get_dirs_in_path(self, path):
"""Returns two lists, the first is a list of all folders in a directory,
the second is a list of files. Also loads the icons for these files and folders.
- For folders, it puts a tk.PhotoImage as the value of the foldericons dictionary
- with the key being the full folder path. For files, it uses the fileicons dictionary,
- with they key being the filetype, e.g. "mp4".
+ For folders, it puts a tk.PhotoImage as the value of the _foldericons dictionary
+ with the key being the full folder path. For files, it uses the _fileicons dictionary,
+ with they key being the filetype, e.g. "mp4". If the file is a shortcut (".lnk") or
+ executable (".exe"), set the whole path as the key, since the icon is different for
+ every file of that type.
Arguments:
path {str} -- full path to the folder
@@ -249,9 +293,15 @@ class FileTree(tk.Frame):
def add(p, type_):
files.append(p)
- if type_ not in self._parent.fileicons:
- self._parent.fileicons[type_] = ImageTk.PhotoImage(
+
+ #if the file is a shortcut, set the key as the whole path
+ if type_ == ".lnk" or type_ == ".exe":
+ self._parent._fileicons[os.path.join(path, p)] = ImageTk.PhotoImage(
self._parent._parent._get_icon(os.path.join(path, p), "small"))
+ else:
+ if type_ not in self._parent._fileicons:
+ self._parent._fileicons[type_] = ImageTk.PhotoImage(
+ self._parent._parent._get_icon(os.path.join(path, p), "small"))
files = []
folders = []
@@ -269,8 +319,8 @@ class FileTree(tk.Frame):
else:
folders.append(p)
- if os.path.join(path, p) not in self._parent.foldericons:
- self._parent.foldericons[os.path.join(path, p)] = ImageTk.PhotoImage(
+ if os.path.join(path, p) not in self._parent._foldericons:
+ self._parent._foldericons[os.path.join(path, p)] = ImageTk.PhotoImage(
self._parent._parent._get_icon(os.path.join(path, p), "small"))
#print("\n\nfolders: ", folders, "\nfiles: ", files)
@@ -283,6 +333,8 @@ def on_click(path):
if __name__ == "__main__":
root = tk.Tk()
browser = TkFileBrowser(root, on_click)
- browser.pack()
+ browser.pack(side = tk.LEFT)
+
+ ttk.Button(root, text = "Goto", command = lambda: browser.see(r"C:\Users\Edward\Documents\random_pyapps")).pack(side = tk.LEFT)
root.mainloop() \ No newline at end of file