diff --git a/plan.txt b/plan.txt new file mode 100644 index 0000000..1b445b4 --- /dev/null +++ b/plan.txt @@ -0,0 +1,28 @@ +V0.01.0 + tidy frames + come up with name + titlebar + add about menu +V0.01.1 + handle permission error + +V0.02 + quick access + add/delete top level node + add/delete links + scrollbar +V0.03 + scrollbar for tree + auto hide +V0.04 + get size and date modified data +V0.05 + Collapse all button for quick access +V0.06 + Expand file types and icons +V0.07 + back/forward navigation +V0.08 + rename files +V0.09 + handle hidden files \ No newline at end of file diff --git a/src/__pycache__/about_screen.cpython-39.pyc b/src/__pycache__/about_screen.cpython-39.pyc new file mode 100644 index 0000000..6a9ea49 Binary files /dev/null and b/src/__pycache__/about_screen.cpython-39.pyc differ diff --git a/src/__pycache__/address_bar.cpython-39.pyc b/src/__pycache__/address_bar.cpython-39.pyc new file mode 100644 index 0000000..2897dcd Binary files /dev/null and b/src/__pycache__/address_bar.cpython-39.pyc differ diff --git a/src/__pycache__/branch_tab.cpython-39.pyc b/src/__pycache__/branch_tab.cpython-39.pyc new file mode 100644 index 0000000..946b543 Binary files /dev/null and b/src/__pycache__/branch_tab.cpython-39.pyc differ diff --git a/src/__pycache__/explorer_backend.cpython-39.pyc b/src/__pycache__/explorer_backend.cpython-39.pyc new file mode 100644 index 0000000..cf4dc20 Binary files /dev/null and b/src/__pycache__/explorer_backend.cpython-39.pyc differ diff --git a/src/__pycache__/root_tab.cpython-39.pyc b/src/__pycache__/root_tab.cpython-39.pyc new file mode 100644 index 0000000..a871742 Binary files /dev/null and b/src/__pycache__/root_tab.cpython-39.pyc differ diff --git a/src/__pycache__/tkexplorer_icons.cpython-39.pyc b/src/__pycache__/tkexplorer_icons.cpython-39.pyc new file mode 100644 index 0000000..e10e80c Binary files /dev/null and b/src/__pycache__/tkexplorer_icons.cpython-39.pyc differ diff --git a/src/__pycache__/treeview_functions.cpython-39.pyc b/src/__pycache__/treeview_functions.cpython-39.pyc new file mode 100644 index 0000000..90089e7 Binary files /dev/null and b/src/__pycache__/treeview_functions.cpython-39.pyc differ diff --git a/src/about_screen.py b/src/about_screen.py new file mode 100644 index 0000000..ca4d46a --- /dev/null +++ b/src/about_screen.py @@ -0,0 +1,24 @@ +import tkinter as tk +from tkinter import * +from tkinter import ttk +from tkinter.ttk import * + +def about(mainapp): + + win = tk.Toplevel() + win.wm_title("About Tk Path Finder") + + l = tk.Label(win, width = 20, text=f"Tk Path Finder Version {mainapp.version}") + l.grid(row=0, column=1, columnspan = 3) + + l2 = tk.Label(win, text=f"Icons From https://icons8.com") + l2.grid(row=1, column=0, columnspan = 5) + + l3 = tk.Label(win, text = ''' + Tk Path Finder makes no promise of warranty, satisfaction, performance, or + anything else. Understand that your use of this tool is completely + at your own risk.''') + l3.grid(row=2, column=0, columnspan = 5) + + b = ttk.Button(win, text="Okay", command=win.destroy) + b.grid(row=3, column=2) \ No newline at end of file diff --git a/src/address_bar.py b/src/address_bar.py new file mode 100644 index 0000000..bee58c7 --- /dev/null +++ b/src/address_bar.py @@ -0,0 +1,19 @@ +import tkinter as tk +from tkinter import * +from tkinter import ttk +from tkinter.ttk import * + +class AddressBarEntry(ttk.Entry): + def __init__(self, mainapp, branch_tab): + super(AddressBarEntry, self).__init__(branch_tab) + self.branch_tab = branch_tab + self.bind('', self.enter_event) + + def update_bar(self): + self.delete(0, END) #deletes the current value + self.insert(0, self.branch_tab.explorer.current_directory) #inserts new value assigned by 2nd parameter + + def enter_event(self, event): + self.branch_tab.explorer.address_bar_updateed(self.get()) + self.branch_tab.update_tab() + self.update_bar() \ No newline at end of file diff --git a/src/branch_tab.py b/src/branch_tab.py new file mode 100644 index 0000000..5a0c201 --- /dev/null +++ b/src/branch_tab.py @@ -0,0 +1,95 @@ +import os +import subprocess +import tkinter as tk +from tkinter import * +from tkinter import ttk +from tkinter.ttk import * + +import address_bar +import explorer_backend +import treeview_functions + +class BranchTab(ttk.Frame): + def __init__(self, root_tab, mainapp, id, text, width): + super(BranchTab, self).__init__(mainapp.notebook) #check if this convention is right + self.mainapp = mainapp + self.id = id + self.root_tab = root_tab + self.text = text + self.width = width + + # GRID + self.tree_colspan = 16 + self.grid_columnconfigure(self.tree_colspan-1, weight=1) + self.grid_rowconfigure(1, weight=1) + + self.explorer = explorer_backend.FileExplorerBackend(self.mainapp) + self.setup_adress_bar() + self.setup_buttons() + self.setup_treeview() + self.address_bar_entry.update_bar() + self.update_treeview() + + def update_tab(self): + self.address_bar_entry.update_bar() + self.update_treeview() + self.root_tab.notebook.tab(self, text=os.path.basename(self.explorer.current_directory)) + + def setup_buttons(self): + #Up a level + ttk.Button(self, text=u'\u2191', command=self.up_one_level, style='primary.TButton').grid(row=0, column=0) + + def setup_adress_bar(self): + self.address_bar_entry = address_bar.AddressBarEntry(self.mainapp, self) + #self.address_bar_entry.pack(expand=True, fill=X) + self.address_bar_entry.grid(row=0, column=1, columnspan=self.tree_colspan-1, sticky='NSEW', pady=self.mainapp.default_pady) + + def setup_treeview(self): + column_names = ['Filename', 'Date Modified', 'Type', 'Size'] + column_widths = [400, 100, 300, 100] + height = 20 + + self.treeview = treeview_functions.create_treeview(self, column_names, column_widths, height) + #self.treeview.pack(expand=True, fill=BOTH) + self.treeview.grid(row=1, column=0, columnspan=16, sticky='NSEW', pady=self.mainapp.default_pady) + self.treeview.bind("", self.OnDoubleClick) + self.treeview.bind("", self.OnRightClick) + + def update_treeview(self): + directory_data = self.explorer.list_directory() + treeview_functions.write_data_to_treeview(self.mainapp, self.treeview, 'replace', directory_data) + + def OnDoubleClick(self, event): + current_selection = treeview_functions.get_current_selection(self.treeview) + if current_selection[1][2] == 'Folder': + directory = current_selection[1][0] + self.explorer.double_clicked_on_directory(directory) + self.update_tab() + else: + self.explorer.double_clicked_on_file(current_selection[1][0]) + + + def OnRightClick(self, event): + iid = self.treeview.identify_row(event.y) + if iid: + self.treeview.selection_set(iid) + popup_menu = tk.Menu(event.widget, tearoff=0) + popup_menu.add_command(label="Open in Text Editor", command=self.open_in_text_editor) + #popup_menu.add_command(label="Delete Root Tab", command=lambda tab=clicked_tab: event.widget.mainapp.delete_root_tab(tab)) + + try: + popup_menu.tk_popup(event.x_root, event.y_root, 0) + finally: + popup_menu.grab_release() + + + def up_one_level(self): + self.explorer.up_one_level() + self.update_tab() + + def open_in_text_editor(self): + current_selection = treeview_functions.get_current_selection(self.treeview) + if current_selection[1][2] != 'Folder': + subprocess.call([r"C:\Program Files (x86)\Notepad++\notepad++.exe", fr"{self.explorer.current_directory}\\{current_selection[1][0]}"]) + + \ No newline at end of file diff --git a/src/explorer_backend.py b/src/explorer_backend.py new file mode 100644 index 0000000..d66ba9d --- /dev/null +++ b/src/explorer_backend.py @@ -0,0 +1,59 @@ +import os +import subprocess + +class FileExplorerBackend: + def __init__(self, mainapp): + self.current_directory = self.get_default_directory() + #self.previous_directories = [] + + def get_default_directory(self): + return os.getcwd() + + def list_directory(self): + # Handle Directories + directory_data = [] + files_dirs = os.listdir(self.current_directory) + directories = [o for o in files_dirs if os.path.isdir(os.path.join(self.current_directory,o))] + for d in directories: + directory_data.append([d, '-', 'Folder', '']) + + # Handle Files + file_data = [] + files = [o for o in files_dirs if not os.path.isdir(os.path.join(self.current_directory,o))] + for f in files: + file_data.append([f, '-', 'File', '']) + + return directory_data + file_data + + def get_file_type(self, filename): + filename, file_extension = os.path.splitext(filename) + print(file_extension) + file_type = 'file' + + return file_type + + def setup_file_type_dict(self): + self.known_file_types = {'.exe': 'application'} + + def double_clicked_on_directory(self, directory): + #self.previous_directories.append(self.current_directory) + self.current_directory = os.path.join(self.current_directory, directory) + + def double_clicked_on_file(self, file): + os.startfile(os.path.join(self.current_directory, file)) + print(os.path.join(self.current_directory, file)) + #subprocess.run(['open', os.path.join(self.current_directory, file)], check=True) + + + def address_bar_updateed(self, directory): + print('bar updated') + print(directory) + if os.path.isdir(directory): + self.current_directory = directory + print('dsd') + + def up_one_level(self): + self.current_directory = os.path.dirname(self.current_directory) + + def update_explorer(self): + pass \ No newline at end of file diff --git a/src/file_menu.py b/src/file_menu.py new file mode 100644 index 0000000..e69de29 diff --git a/src/main.py b/src/main.py new file mode 100644 index 0000000..f6eb496 --- /dev/null +++ b/src/main.py @@ -0,0 +1,106 @@ +import tkinter as tk +from tkinter import * +from tkinter import ttk +from tkinter.ttk import * + +from ttkbootstrap import Style + +import about_screen +import root_tab +import tkexplorer_icons + +class MainApplication(ttk.Frame): + def __init__(self, parent, *args, **kwargs): + ttk.Frame.__init__(self, parent, *args, **kwargs) + self.parent = parent + self.root_tabs = {} + self.id = 0 + self.setup_variables() + + # Styles + self.style = Style('darkly') + self.default_pady = 10 + tkexplorer_icons.setup_icons(self) + + self.setup_menu() + + self.setup_main_frames() + self.setup_notebook() + self.setup_tabs() + + def setup_variables(self): + self.version = '0.01.0' + self.parent.title(f"Tk Path Finder V{self.version}") + + def setup_menu(self): + menu = tk.Menu(self.master) + self.master.config(menu=menu) + + # ________ ABOUT ________ + about_menu = tk.Menu(menu, tearoff = 0) + menu.add_cascade(label='About',menu=about_menu) + about_menu.add_command(label = 'About Tk Path Finder', command = lambda self=self: about_screen.about(self)) + + def setup_notebook(self): + self.notebook = ttk.Notebook(self.container) + self.notebook.pack(expand=True, fill=BOTH, side=LEFT) + self.notebook.bind('', root_tab.right_click) + self.notebook.mainapp = self + + def setup_tabs(self): + if self.root_tabs == {}: + tab = self.create_root_tab() + self.root_tabs = {0: tab} + + def create_root_tab(self): + tab = root_tab.RootTab(self, self.id, self.id, 40) + self.notebook.add(tab, text=f'{str(self.id).ljust(20)}') + + self.id += 1 + + return tab + + def delete_root_tab(self, tab): + if len(self.notebook.tabs()) > 1: + self.notebook.forget(tab) + + def delete_branch_tab(self, tab): + if len(tab.root_tab.notebook.tabs()) > 1: + tab.root_tab.notebook.forget(tab) + + def setup_main_frames(self): + #self.top_frame = Frame(self.parent) # for toolbar and address bar + #self.top_frame.grid(row=0,column=0, sticky="n") + + self.rootpane = ttk.PanedWindow(self.parent, orient=tk.HORIZONTAL) + self.rootpane.pack(expand=True, fill=BOTH, side=LEFT) + #self.rootpane.grid(row=1,column=0, columnspan=4,sticky="nsew") + + self.sidebar_frame = ttk.Frame() + self.sidebar_frame.grid_rowconfigure(1, weight=1) + self.sidebar_frame.grid_columnconfigure(19, weight=1) + self.rootpane.add(self.sidebar_frame) + + self.container = tk.Frame(self.rootpane, bg='pink') + self.container.pack(expand=True, fill=BOTH, side=LEFT) + #self.container.grid_columnconfigure(0, weight=1) + + self.rootpane.add(self.container,)#stretch="always") + + ttk.Label(self.sidebar_frame, text='Quick Access').pack() + #ttk.Button(self.container, text='Add Root', command=self.create_root_tab).pack() +if __name__ == "__main__": + root = tk.Tk() + root.resizable(width=tk.TRUE, height=tk.TRUE) + #MainApplication(root).pack(side="top", fill="both", expand=True) + MA = MainApplication(root) + #MA.pack(expand=True, fill=BOTH, side=LEFT) + #MA.grid(row=1, columnspan=4, sticky='nsew') + # root.bind('', lambda event, MA=MA: fm.save(event, MA)) + # root.bind('', lambda event, MA=MA: fm.save_as(event, MA)) + # root.bind('', MA.states.undo) + # root.bind('', MA.states.redo) + + #root.geometry('{}x{}'.format(MA.screen_width, MA.screen_height)) + root.state('zoomed') #mamimise window + root.mainloop() \ No newline at end of file diff --git a/src/notebook_test.py b/src/notebook_test.py new file mode 100644 index 0000000..bdb649c --- /dev/null +++ b/src/notebook_test.py @@ -0,0 +1,26 @@ +from tkinter.ttk import Notebook + +class Autoresized_Notebook(Notebook): + def __init__(self, master=None, **kw): + + Notebook.__init__(self, master, **kw) + self.bind("<>", self._on_tab_changed) + + def _on_tab_changed(self,event): + event.widget.update_idletasks() + + tab = event.widget.nametowidget(event.widget.select()) + event.widget.configure(height=tab.winfo_reqheight()) + +if __name__== "__main__": + from tkinter import Frame, Tk + root = Tk() + + notebook = Autoresized_Notebook(root) + notebook.add(Frame(notebook, width=400, height=200, name="a"),text="TAB 1") + notebook.add(Frame(notebook, width=400, height=300, name="b"),text="TAB 2") + notebook.add(Frame(notebook, width=400, height=100, name="c"),text="TAB 3") + + notebook.pack() + + root.mainloop() \ No newline at end of file diff --git a/src/rename_window.py b/src/rename_window.py new file mode 100644 index 0000000..91b1ab6 --- /dev/null +++ b/src/rename_window.py @@ -0,0 +1,9 @@ +import tkinter as tk +from tkinter import * +from tkinter import ttk +from tkinter.ttk import * + +class RenameWindow: + def __init__(self, lopa, mainapp, master, side, row_data): + top=self.top=Toplevel(master) + top.grab_set() \ No newline at end of file diff --git a/src/root_tab.py b/src/root_tab.py new file mode 100644 index 0000000..01bbcc2 --- /dev/null +++ b/src/root_tab.py @@ -0,0 +1,72 @@ +import tkinter as tk +from tkinter import * +from tkinter import ttk +from tkinter.ttk import * +from tkinter import simpledialog + +import branch_tab + +def right_click(event): + clicked_tab = event.widget.mainapp.notebook.tk.call(event.widget.mainapp.notebook._w, "identify", "tab", event.x, event.y) + #tab_object = event.widget.nametowidget(event.widget.select(clicked_tab)) + tab_object = event.widget.nametowidget(event.widget.select()) + popup_menu = tk.Menu(event.widget, tearoff=0) + popup_menu.add_command(label="Add Root Tab", command=event.widget.mainapp.create_root_tab) + popup_menu.add_command(label="Delete Root Tab", command=lambda tab=clicked_tab: event.widget.mainapp.delete_root_tab(tab)) + popup_menu.add_command(label="Rename Root Tab", command=tab_object.rename_tab) + + try: + popup_menu.tk_popup(event.x_root, event.y_root, 0) + finally: + popup_menu.grab_release() + +def right_click_branch(event): + tab_object = event.widget.nametowidget(event.widget.select()) + #clicked_tab = event.widget.mainapp.notebook.tk.call(event.widget.mainapp.notebook._w, "identify", "tab", event.x, event.y) + + popup_menu = tk.Menu(event.widget, tearoff=0) + popup_menu.add_command(label="Add Branch Tab", command=event.widget.create_branch_tab) + popup_menu.add_command(label="Delete Branch Tab", command=lambda tab=tab_object: event.widget.mainapp.delete_branch_tab(tab)) + + try: + popup_menu.tk_popup(event.x_root, event.y_root, 0) + finally: + popup_menu.grab_release() + +class RootTab(ttk.Frame): + def __init__(self, mainapp, id, text, width): + super(RootTab, self).__init__(mainapp.notebook) #check if this convention is right + self.mainapp = mainapp + self.id = id + self.text = text + self.width = width + + self.id = 0 + self.branch_tabs = {} + + self.setup_notebook() + self.notebook.bind('', right_click_branch) + + def setup_notebook(self): + self.notebook = ttk.Notebook(self) + self.notebook.pack(expand=True, fill=BOTH, side=LEFT) + self.notebook.mainapp = self.mainapp + self.setup_tabs() + self.notebook.create_branch_tab = self.create_branch_tab + + def setup_tabs(self): + if self.branch_tabs == {}: + tab = self.create_branch_tab() + self.branch_tabs = {0: tab} + + def create_branch_tab(self): + tab = branch_tab.BranchTab(self, self.mainapp, self.id, self.id, 40) + self.notebook.add(tab, text = "Desktop") + self.id += 1 + + return tab + + def rename_tab(self): + new_name = simpledialog.askstring(title = "Rename Tab", prompt = "New Name:".ljust(100), initialvalue=self.text) + if new_name != None: + self.mainapp.notebook.tab(self, text=f'{str(new_name).ljust(20)}') diff --git a/src/sidebar_tree.py b/src/sidebar_tree.py new file mode 100644 index 0000000..e69de29 diff --git a/src/tkexplorer_icons.py b/src/tkexplorer_icons.py new file mode 100644 index 0000000..c27230a --- /dev/null +++ b/src/tkexplorer_icons.py @@ -0,0 +1,22 @@ +from PIL import Image, ImageTk +import base64 +import io + +def setup_icons(mainapp): + + size = 18,18 + + data = 'iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABmJLR0QA/wD/AP+gvaeTAAABfklEQVRoge2XPUvDUBSG39h84CyU1ioOMXToIDWCf8Ctf8DBTfE3ODYogoOIg4MOgoi/xN3FRRARdNChflBQ8tHkOhVyAzVgjmkTzgMZTnJ5733uPQkEYBiGYTKgxIuXS3QU4FQAjT/mCQD3ULBf38BF9uWlIwk8neMZwBxFsBBwFjbRpcj6DUng4QyCOP/A3MYOcaaEJHB3Qi4AARxFBvZaW3inzgYSArfH9AJV00bVXAEUJX1wCgP3O+z3Hp2Ztevd4T0p9eaQVqBu2ahZNmUkAvcr1NtX6rBWpYcB3USN5jJqi21ARHShADRjuhKvZYFB9glU3cB8cwmzVgtAmD0wbb54sdpZh6obNMnEOz8KSUDVtNwmpkKVy2ItHkgKFGz3AT6B8VMyAW6h/CmZQNFbSPAJ5E/J3oHCC3AL5U9C4P//oKjhFho3JRPgFsqfcp2A73qhbmiVUYMnAd8NpG/9VLz4eO07vuuFEBEm8fJdL+y9fXZz3TGGYZhy8wPLqL/TAN/hMAAAAABJRU5ErkJggg==' + mainapp.folder_icon2 = ImageTk.PhotoImage(decode_base64_image(size, data)) + + data = 'iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABmJLR0QA/wD/AP+gvaeTAAACxUlEQVRIidWXS2gTURSG/8m8Mkk6maQvlWhJU7WFWqtVoUpFhIALF10YcFFEl66K4MJNISjYTRHURelGKmKFuhAUBCl24VZU0KZg0zR9JE3b1GTiZJLahBkXNW3TxHbyqMV/deecM+e759wLhwvskYithicv310WeOPFQhOJUpyeHQv1uN03xKJ2MvR69JFahL77A+rTVyPRO73PLVo4uqJ2l0cUqcOljlPCyeM2760Hw9Z/BgYAmqLQ6TxX2d5YO7ETvKzgNTipCV52sFZ4WcGiFEckJiESkyDJCZw/fayy1W7x5btwVLmg+6utCC7+QESUsuxnWhqFZGL1PoCbuwLm9Cwa6g7k9X3xeFNbbbtyxlq0Z2BNrf405i0oaVvz4fKAtSQqVGWruNDN/f8VA4BKEFCgwGAhEBBD0IEAQzGgK+iWosBaK/44/RUT4UkYSRYmIwcASCorkIzRdvfbhy98y3Pdz671LWkGT82FtvWn0ipmViYhExJqa4QsH6UjYaupYmzVVVdN01yjMHjvyuPrPT5NYAtfsa3/c8ADmZRg4riNf/QWWPUCfKJ/zUAALXZHayq1Ougadl3QBjab/upTVAWh5Dxqq81ZdqteQL3ZvgH+o2Z7w1nxW7y75Ms1K4VgEGgtaQAALE3rrDzvLPlyhcdDIA0GABvtzawBwCHY12Mz1bM0e6jk6aSqyvo6097N2vydARM6gi0ZzDEGJJUYKB0Jn+hfT+4Q7Kg32zEyM5rzTzqdjpQ8nU7YmnKG/06KJxJjJYPNXAX04ABVW3wgvLQwHxX7yjKPnU0dWAhnPyB8oj+nzfFk4pc3GOwf6HKP55zxT1n+MPTmPVsImKEZI8tUHfHEpo466vbxeobJiQmElxa8wWB/b+ftu0Cet1Mpcg27yHqqrdvK806O1R9UVJVTFGVZkmXPfFTsG+hyj2difwPxFi1bPxhiJQAAAABJRU5ErkJggg==' + mainapp.new_icon2 = ImageTk.PhotoImage(decode_base64_image(size, data)) + +def decode_base64_image(size, data): + + msg = base64.b64decode(data) + buf = io.BytesIO(msg) + + i = Image.open(buf) + i.thumbnail(size, Image.ANTIALIAS) + return i \ No newline at end of file diff --git a/src/toolbar.py b/src/toolbar.py new file mode 100644 index 0000000..e69de29 diff --git a/src/treeview_functions.py b/src/treeview_functions.py new file mode 100644 index 0000000..e234424 --- /dev/null +++ b/src/treeview_functions.py @@ -0,0 +1,108 @@ +import pandas as pd +import tkinter as tk +from tkinter import * +from tkinter import ttk +from tkinter.ttk import * +import string + + +def create_treeview(frame, column_names, column_widths, height): + + letters = string.ascii_uppercase + cols = [] + for i in range(len(column_names)-1): + cols.append(letters[i]) + + tree = ttk.Treeview(frame, selectmode="extended",columns=cols,height = height) + cols.insert(0, "#0") + cols = tuple(cols) + + for idx, col in enumerate(cols): + tree.heading(col, text=column_names[idx]) + tree.column(col,minwidth=0,width=column_widths[idx], stretch='NO') + + return tree + +def get_columns_values(treeview, column): + values = [] + + children = treeview.get_children() + + for child in children: + if column == 0: + values.append(treeview.item(child, 'text')) + else: + values.append((treeview.item(child, 'values'))[column-1]) + return values + + +def get_all_treeview_items(treeview): + + treeview_data = [] + + children = treeview.get_children() + + for child in children: + treeview_data.append([treeview.item(child, 'text')]) + values = treeview.item(child, 'values') + for x in values: + treeview_data[-1].append(x) + return treeview_data + +def write_data_to_treeview(mainapp, treeview, mode, data): + + if mode == 'replace': + treeview.delete(*treeview.get_children()) + + for d in data: + image = mainapp.new_icon2 + if d[2] == 'Folder': + image = mainapp.folder_icon2 + if len(d) > 1: + treeview.insert('', 'end', text=d[0], values=tuple(d[1:]), image=image) + else: + treeview.insert('', 'end', text=d[0]) + +def get_treeview_headers(treeview): + + columns = list(treeview['columns']) + columns.insert(0, '#0') + + return [treeview.heading(x)['text'] for x in columns] + +def treeview_to_df(treeview): + treeview_data = {} + + #Columns + headers = get_treeview_headers(treeview) + + for column, h in enumerate(headers): + treeview_data[h] = get_columns_values(treeview, column) + + df = pd.DataFrame.from_dict(treeview_data) + + return df + +def del_selected_items(treeview, msg=False): + selected_item = treeview.selection() + if selected_item: + + if msg: #if we require a messagebox + MsgBox = tk.messagebox.askquestion ('Delete Selected Item??','This Cannont Be Undone!',icon = 'warning') + if MsgBox == 'yes': + treeview.delete(selected_item) + else: + treeview.delete(selected_item) + + #return MsgBox + +def get_current_selection(treeview): + + item = treeview.selection()[0] + index = treeview.index(item) + + data = list(treeview.item(item,"values")) + data.insert(0, treeview.item(item,"text")) + + + return index, data \ No newline at end of file