Sep-26-2023, 08:08 PM
A quick and dirty (oh so dirty) example of using the filter idea above in a tkinter window that displays a dataframe.
import tkinter as tk import pandas as pd from dataclasses import dataclass from random import choices class Window(tk.Tk): def __init__(self, dataframe): super().__init__() self.df = dataframe self.columns = {} row = tk.Frame(self) row.pack(side=tk.TOP) for column in dataframe: col = tk.Frame(row) col.pack(side=tk.LEFT, padx=5, pady=5) tk.Label(col, text=column).pack() values = sorted(set(dataframe[column].values)) var = tk.Variable(self, values) selector = tk.Listbox( col, width=10, height=10, listvariable=var, selectmode=tk.MULTIPLE, exportselection=False, ) selector.pack() selector.bind("<<ListboxSelect>>", self.filter) selector.var = var self.columns[column] = selector self.table = tk.Label(self) self.table.pack(expand=True, fill=tk.BOTH) self.filter() def filter(self, *args): df = self.df.copy() for column, lbox in self.columns.items(): if selection := lbox.curselection(): choices = [lbox.get(index) for index in selection] df = df[df[column].isin(choices)] self.table["text"] = str(df) # Make a dataframe for demonstrating filter. letters = "ABCDEIOU" numbers = [str(x) for x in range(1, 10)] mixed = [f"{letter}{number}" for letter in letters for number in numbers] df = pd.DataFrame( { "Letters": choices(letters, k=20), "Numbers": choices(numbers, k=20), "Mixed": choices(mixed, k=20), } ) Window(df).mainloop()