按需打开目录CSV文件并在Tkinter表格展示及报错解决
解决Tkinter中CSV文件选择与表格展示的报错问题
问题背景
你需要实现一个功能:让用户在Tkinter界面中选择指定目录下的CSV文件,然后将文件内容以表格形式展示出来。但现有代码运行时遇到了TypeError: string indices must be integers的报错,同时文件选择的参数也存在问题。
报错原因分析
先看你代码里的循环部分:
for row in attend: Id = row['Id'] name = row['Name'] date = row['Date'] time = row['Time'] tree.insert("", 100000, values=(Id, name, date,time))
当你直接遍历pandas.DataFrame对象时,默认是遍历列名,而不是行数据。所以这里的row其实是字符串(比如"Id"、"Name"这些列名),用row['Id']自然会报错——字符串的索引只能是整数,不能是字符串。
另外,你的filedialog.askopenfilename参数也有问题:filetypes参数需要传入一个元组的元组,但你现在的写法把两个元组分开作为独立参数了,这会导致语法错误。
解决方案
我们分两步修复:
1. 修复文件选择功能
修正filetypes参数的格式,确保它是包含两个元组的元组,同时检查语法括号是否正确:
filename = filedialog.askopenfilename( initialdir="C:/Users/Ahmad Jan Ahmadi/Desktop/FYP-11 Final/Attendance/", title="Select Attendance File", filetypes=(("Csv Files", "*.csv"), ("All Files", "*.*")) )
这样就能正确弹出文件选择对话框,只显示CSV文件和所有文件选项。
2. 修复CSV数据遍历与表格插入
使用pandas.DataFrame.iterrows()方法来遍历每一行数据,这个方法会返回每行的索引和对应的Series对象,你可以直接通过列名访问数据:
# 先清空Treeview之前的内容(可选,避免重复插入) for item in tree.get_children(): tree.delete(item) # 遍历CSV的每一行 for index, row in attend.iterrows(): Id = row['Id'] name = row['Name'] date = row['Date'] time = row['Time'] # 插入到Treeview,用END追加到末尾更合理 tree.insert("", "end", values=(Id, name, date, time))
另外,建议在插入前清空Treeview的原有内容,避免多次选择文件后内容重复堆积。
完整的open_att函数示例
假设你已经初始化了Tkinter的Treeview组件,完整的函数如下:
import tkinter as tk from tkinter import filedialog, ttk import pandas as pd def open_att(): # 修复文件选择参数 filename = filedialog.askopenfilename( initialdir="C:/Users/Ahmad Jan Ahmadi/Desktop/FYP-11 Final/Attendance/", title="Select Attendance File", filetypes=(("Csv Files", "*.csv"), ("All Files", "*.*")) ) # 判断用户是否选择了文件(避免取消选择时报错) if not filename: return attend = pd.read_csv(filename) # 清空Treeview原有内容 for item in tree.get_children(): tree.delete(item) # 遍历每行数据插入表格 for index, row in attend.iterrows(): Id = row['Id'] name = row['Name'] date = row['Date'] time = row['Time'] tree.insert("", "end", values=(Id, name, date, time))
额外提示
- 确保你的Treeview组件已经正确配置了列,比如:
# 初始化Treeview tree = ttk.Treeview(root, columns=("Id", "Name", "Date", "Time"), show="headings") # 设置列标题 tree.heading("Id", text="ID") tree.heading("Name", text="Name") tree.heading("Date", text="Date") tree.heading("Time", text="Time") # 设置列宽(可选) tree.column("Id", width=80) tree.column("Name", width=150) tree.column("Date", width=100) tree.column("Time", width=100) tree.pack()
- 加入用户取消文件选择的判断(
if not filename: return),避免后续代码读取空路径报错。
内容的提问来源于stack exchange,提问作者ahmad jan ahmadi
相关产品推荐
相关产品推荐

