You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 22:10:12