Skip to content

Instantly share code, notes, and snippets.

@Yousuf28
Forked from RamonWill/DataFrameSearch.py
Created September 26, 2023 02:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Yousuf28/5210ed8fb0317a0ff4ff2c6b1615b054 to your computer and use it in GitHub Desktop.
Save Yousuf28/5210ed8fb0317a0ff4ff2c6b1615b054 to your computer and use it in GitHub Desktop.
The code from my tutorial series on how to create a CSV/Dataframe viewer in Tkinter
# Tutorial playlist https://www.youtube.com/playlist?list=PLCQT7jmSF-LrwYppkB3Xdbe6QC81-ozmT
import tkinter as tk
from pathlib import Path
from tkinter import ttk
from TkinterDnD2 import DND_FILES, TkinterDnD
import pandas as pd
class Application(TkinterDnD.Tk):
def __init__(self):
super().__init__()
self.title("CSV Viewer")
self.main_frame = tk.Frame(self)
self.main_frame.pack(fill="both", expand="true")
self.geometry("900x500")
self.search_page = SearchPage(parent=self.main_frame)
class DataTable(ttk.Treeview):
def __init__(self, parent):
super().__init__(parent)
scroll_Y = tk.Scrollbar(self, orient="vertical", command=self.yview)
scroll_X = tk.Scrollbar(self, orient="horizontal", command=self.xview)
self.configure(yscrollcommand=scroll_Y.set, xscrollcommand=scroll_X.set)
scroll_Y.pack(side="right", fill="y")
scroll_X.pack(side="bottom", fill="x")
self.stored_dataframe = pd.DataFrame()
def set_datatable(self, dataframe):
self.stored_dataframe = dataframe
self._draw_table(dataframe)
def _draw_table(self, dataframe):
self.delete(*self.get_children())
columns = list(dataframe.columns)
self.__setitem__("column", columns)
self.__setitem__("show", "headings")
for col in columns:
self.heading(col, text=col)
df_rows = dataframe.to_numpy().tolist()
for row in df_rows:
self.insert("", "end", values=row)
return None
def find_value(self, pairs):
# pairs is a dictionary
new_df = self.stored_dataframe
for col, value in pairs.items():
query_string = f"{col}.str.contains('{value}')"
new_df = new_df.query(query_string, engine="python")
self._draw_table(new_df)
def reset_table(self):
self._draw_table(self.stored_dataframe)
class SearchPage(tk.Frame):
def __init__(self, parent):
super().__init__(parent)
self.file_names_listbox = tk.Listbox(parent, selectmode=tk.SINGLE, background="darkgray")
self.file_names_listbox.place(relheight=1, relwidth=0.25)
self.file_names_listbox.drop_target_register(DND_FILES)
self.file_names_listbox.dnd_bind("<<Drop>>", self.drop_inside_list_box)
self.file_names_listbox.bind("<Double-1>", self._display_file)
self.search_entrybox = tk.Entry(parent)
self.search_entrybox.place(relx=0.25, relwidth=0.75)
self.search_entrybox.bind("<Return>", self.search_table)
# Treeview
self.data_table = DataTable(parent)
self.data_table.place(rely=0.05, relx=0.25, relwidth=0.75, relheight=0.95)
self.path_map = {}
def drop_inside_list_box(self, event):
file_paths = self._parse_drop_files(event.data)
current_listbox_items = set(self.file_names_listbox.get(0, "end"))
for file_path in file_paths:
if file_path.endswith(".csv"):
path_object = Path(file_path)
file_name = path_object.name
if file_name not in current_listbox_items:
self.file_names_listbox.insert("end", file_name)
self.path_map[file_name] = file_path
def _display_file(self, event):
file_name = self.file_names_listbox.get(self.file_names_listbox.curselection())
path = self.path_map[file_name]
df = pd.read_csv(path)
self.data_table.set_datatable(dataframe=df)
def _parse_drop_files(self, filename):
# 'C:/Users/Owner/Downloads/RandomStock Tickers.csv C:/Users/Owner/Downloads/RandomStockTickers.csv'
size = len(filename)
res = [] # list of file paths
name = ""
idx = 0
while idx < size:
if filename[idx] == "{":
j = idx + 1
while filename[j] != "}":
name += filename[j]
j += 1
res.append(name)
name = ""
idx = j
elif filename[idx] == " " and name != "":
res.append(name)
name = ""
elif filename[idx] != " ":
name += filename[idx]
idx += 1
if name != "":
res.append(name)
return res
def search_table(self, event):
# column value. [[column,value],column2=value2]....
entry = self.search_entrybox.get()
if entry == "":
self.data_table.reset_table()
else:
entry_split = entry.split(",")
column_value_pairs = {}
for pair in entry_split:
pair_split = pair.split("=")
if len(pair_split) == 2:
col = pair_split[0]
lookup_value = pair_split[1]
column_value_pairs[col] = lookup_value
self.data_table.find_value(pairs=column_value_pairs)
if __name__ == "__main__":
root = Application()
root.mainloop()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment