基于Status Blokace列实现行色区分及列字母序排序(Python)
Python-Tkinter 表格行着色与排序优化方案
以下是满足你需求的优化代码,同时修正了代码规范问题:
import tkinter as tk from tkinter import ttk import pandas as pd # 定义常量,避免硬编码路径 EXCEL_PATH = r"C:\Users\ondresab\Documents\Data.xlsx" # 定义状态对应的背景色 STATUS_COLORS = { "K odblokovani": "#f0f0f0", # 浅灰色 "K zablokovani": "#d0d0d0" # 深灰色 } def load_and_filter_data(): """加载并筛选数据,同时按Status Blokace排序""" data = pd.read_excel(EXCEL_PATH) # 筛选指定状态的数据 filtered_data = data[data['Status Blokace'].isin(["K odblokovani", "K zablokovani"])] # 按Status Blokace列字母排序 sorted_data = filtered_data.sort_values(by='Status Blokace') return sorted_data.reset_index(drop=True) # 重置索引,避免显示原Excel的行号 def save_to_excel(data): """保存数据到Excel""" data.to_excel(EXCEL_PATH, index=False) def change_status(data, index): """修改指定行的状态并刷新显示""" current_status = data.at[index, 'Status Blokace'] if current_status == "K odblokovani": data.at[index, 'Status Blokace'] = "Odblokovany" elif current_status == "K zablokovani": data.at[index, 'Status Blokace'] = "Zablokovany" save_to_excel(data) display_data(data) def display_data(data): """显示数据表格,根据状态设置行背景色""" # 清空之前的控件 for widget in form.winfo_children(): widget.destroy() # 创建表头 for col_idx, col_name in enumerate(columns): ttk.Label(form, text=col_name, font=('Arial', 10, 'bold')).grid(row=0, column=col_idx, padx=5, pady=2) # 遍历数据行 for row_idx, (_, row) in enumerate(data.iterrows(), start=1): # 表头占第0行,数据从第1行开始 status = row['Status Blokace'] # 获取当前状态对应的背景色 bg_color = STATUS_COLORS.get(status, "#ffffff") # 为每行的标签设置背景色 ttk.Label(form, text=row['Employee ID'], background=bg_color).grid(row=row_idx, column=0, padx=5, pady=1) ttk.Label(form, text=row['Login'], background=bg_color).grid(row=row_idx, column=1, padx=5, pady=1) ttk.Label(form, text=row['Meno'], background=bg_color).grid(row=row_idx, column=2, padx=5, pady=1) ttk.Label(form, text=row['Datum zmeny statusu'], background=bg_color).grid(row=row_idx, column=3, padx=5, pady=1) ttk.Label(form, text=status, background=bg_color).grid(row=row_idx, column=4, padx=5, pady=1) ttk.Label(form, text=row['Duvod Blokace'], background=bg_color).grid(row=row_idx, column=5, padx=5, pady=1) # 添加操作按钮 ttk.Button(form, text="Done", command=lambda idx=row_idx-1, d=data: change_status(d, idx)).grid(row=row_idx, column=6, padx=5, pady=1) def update_data(): """刷新数据并重新显示""" new_data = load_and_filter_data() display_data(new_data) return new_data if __name__ == "__main__": root = tk.Tk() root.title("Data Form") root.geometry("1000x800") # 加宽窗口,避免内容挤在一起 # 初始化数据 data = load_and_filter_data() # 创建刷新按钮 refresh_button = ttk.Button(root, text="Refresh", command=lambda: update_data()) refresh_button.pack(pady=10) # 定义列名 columns = ["Employee ID", "Login", "Meno", "Datum zmeny statusu", "Status Blokace", "Duvod Blokace", "Action"] # 创建表格容器 form = ttk.Frame(root) form.pack(padx=10, fill=tk.BOTH, expand=True) # 显示初始数据 display_data(data) root.mainloop()
关键修改说明:
- 行颜色区分:
- 定义
STATUS_COLORS字典映射状态到对应的颜色值 - 在
display_data中根据每行的Status Blokace值获取颜色,设置给该行的所有标签
- 定义
- 按状态排序:
- 在
load_and_filter_data函数中,用sort_values(by='Status Blokace')对筛选后的数据进行排序 - 调用
reset_index(drop=True)重置索引,避免显示原Excel的行号
- 在
- 代码规范优化:
- 提取Excel路径为常量
EXCEL_PATH,避免重复硬编码 - 拆分功能为独立函数(加载数据、保存数据、修改状态、显示数据),降低耦合度
- 移除全局变量,通过函数参数传递数据
- 添加表头显示,提升表格可读性
- 调整窗口大小和控件间距,优化显示效果
- 提取Excel路径为常量
内容的提问来源于stack exchange,提问作者Ondrik terry
相关产品推荐
相关产品推荐

