基于Tkinter和Pandas实现类Excel多列过滤的问题求助
问题修复方案
问题1:级联过滤失效修复
原因
当前代码每次过滤都直接从原始df生成新结果,未基于历史过滤后的数据集二次过滤,导致无法保留多条件交集。
修复代码
修改apply_filter函数,基于历史过滤结果迭代:
def apply_filter(): selected_column = column_var.get() selected_item = item_var.get() if selected_column and selected_item: # 有过滤历史则用最后一次结果,无则用原始数据 base_df = filter_history[-1] if filter_history else df filtered_df = base_df[base_df[selected_column] == selected_item] filter_history.append(filtered_df) display_filtered_dataframe(filter_history)
同步修改update_items函数,让可选项基于当前过滤后的数据:
def update_items(event): selected_column = column_var.get() if selected_column: base_df = filter_history[-1] if filter_history else df items = base_df[selected_column].unique() item_var.set('') item_dropdown['values'] = list(map(str, items))
问题2:Treeview列标题不显示修复
原因
代码反复对#0列(索引列)设置标题,未针对每个数据列单独配置heading和column属性。
修复代码
修改display_filtered_dataframe中的列配置逻辑:
def display_filtered_dataframe(dataframe): for row in treeview.get_children(): treeview.delete(row) if dataframe: current_df = dataframe[-1] columns = current_df.columns treeview["columns"] = ["#0"] + list(columns) # 单独设置索引列 treeview.heading("#0", text="Index") treeview.column("#0", width=100) # 遍历配置每个数据列的标题和宽度 for col in columns: treeview.heading(col, text=col, command=lambda col=col: print(col)) treeview.column(col, width=100, anchor='e') for i, row in current_df.iterrows(): treeview.insert('', 'end', values=[i] + list(row))
同时修正初始化Treeview的代码:
# 初始化Treeview treeview = ttk.Treeview(root, columns=["#0"] + list(df.columns), show='headings') treeview.heading("#0", text="Index") treeview.column("#0", width=100) for col in df.columns: treeview.heading(col, text=col, command=lambda col=col: print(col)) treeview.column(col, width=100, anchor='e')
完整修正代码
from win32com.shell import shell, shellcon import pandas as pd import openpyxl from openpyxl import load_workbook import numpy as np import time from tkinter import * from tkinter import ttk,filedialog import tkinter as tk # 补充数据初始化(示例:读取Excel文件) # df = pd.read_excel("your_data_file.xlsx") def apply_filter(): selected_column = column_var.get() selected_item = item_var.get() if selected_column and selected_item: base_df = filter_history[-1] if filter_history else df filtered_df = base_df[base_df[selected_column] == selected_item] filter_history.append(filtered_df) display_filtered_dataframe(filter_history) def update_items(event): selected_column = column_var.get() if selected_column: base_df = filter_history[-1] if filter_history else df items = base_df[selected_column].unique() item_var.set('') item_dropdown['values'] = list(map(str, items)) def reset_filter(): filter_history.clear() display_filtered_dataframe([df]) column_var.set('') item_var.set('') def display_filtered_dataframe(dataframe): for row in treeview.get_children(): treeview.delete(row) if dataframe: current_df = dataframe[-1] columns = current_df.columns treeview["columns"] = ["#0"] + list(columns) treeview.heading("#0", text="Index") treeview.column("#0", width=100) for col in columns: treeview.heading(col, text=col, command=lambda col=col: print(col)) treeview.column(col, width=100, anchor='e') for i, row in current_df.iterrows(): treeview.insert('', 'end', values=[i] + list(row)) # 主窗口创建 root = tk.Tk() root.title("Excel Data Filter") # 列选择控件 column_var = tk.StringVar() column_label = tk.Label(root, text="Select Column:") column_label.pack() column_listbox = tk.Listbox(root, selectmode=tk.SINGLE) column_listbox.pack() for column in df.columns: column_listbox.insert(tk.END, column) # 项选择下拉框 item_var = tk.StringVar() item_label = tk.Label(root, text="Select Item:") item_label.pack() item_dropdown = ttk.Combobox(root, textvariable=item_var, state='readonly') item_dropdown.pack() # 功能按钮 filter_button = tk.Button(root, text="Apply Filter", command=apply_filter) filter_button.pack() reset_button = tk.Button(root, text="Reset Filter", command=reset_filter) reset_button.pack() # 表格控件 treeview = ttk.Treeview(root, columns=["#0"] + list(df.columns), show='headings') treeview.heading("#0", text="Index") treeview.column("#0", width=100) for col in df.columns: treeview.heading(col, text=col, command=lambda col=col: print(col)) treeview.column(col, width=100, anchor='e') # 滚动条配置 tree_scroll_y = ttk.Scrollbar(root, orient='vertical', command=treeview.yview) tree_scroll_x = ttk.Scrollbar(root, orient='horizontal', command=treeview.xview) treeview.configure(yscrollcommand=tree_scroll_y.set, xscrollcommand=tree_scroll_x.set) treeview.pack(expand=True, fill='both') tree_scroll_y.pack(side='right', fill='y') tree_scroll_x.pack(side='bottom', fill='x') # 过滤历史存储 filter_history = [] # 列选择绑定事件 def on_select(event): selected_index = column_listbox.curselection() if selected_index: selected = column_listbox.get(selected_index[0]) column_var.set(selected) update_items(None) column_listbox.bind("<<ListboxSelect>>", on_select) # 初始加载数据 display_filtered_dataframe([df]) root.mainloop()
额外说明
- 需补充
df的初始化代码(如读取Excel文件)才能正常运行。 - 优化了Treeview布局,添加
expand=True, fill='both'让表格自适应窗口大小。
内容的提问来源于stack exchange,提问作者Biplab1985
相关产品推荐
相关产品推荐

