Python GUI读取文件遇FileNotFoundError,求文件读取与数值相减解决方案
问题描述
编写了一段Python GUI代码,目标是让用户选择三个不同文件,读取内容后进行数值相减操作。但点击执行按钮时出现FileNotFoundError,报错信息如下:
return self.func(*args) with open('CHGCAR1', 'r') as f: FileNotFoundError: [Errno 2] No such file or directory: 'CHGCAR1'
涉及的charge_density函数代码:
def charge_density(): with open('CHGCAR1', 'r') as f: CHGCAR1 = f.read() CHGCAR1_ints = [safeFloat(x) for x in CHGCAR1.split()] print(CHGCAR1_ints) CHGCAR1_ints_1 = [c for c in CHGCAR1_ints if c is not None] print(CHGCAR1_ints_1) with open('CHGCAR2', 'r') as f: CHGCAR2 = f.read() CHGCAR2_ints = [safeFloat(x) for x in CHGCAR2.split()] print(CHGCAR2_ints) CHGCAR2_ints_2 = [c for c in CHGCAR2_ints if c is not None] print(CHGCAR2_ints_2) with open('CHGCAR3', 'r') as f: CHGCAR3 = f.read() CHGCAR3_ints = [safeFloat(x) for x in CHGCAR3.split()] print(CHGCAR3_ints) CHGCAR3_ints_3 = [c for c in CHGCAR3_ints if c is not None] print(CHGCAR3_ints_3) with open("CHGCAR_final.txt", 'w') as f: for i in range( min( len(CHGCAR1_ints_1), len(CHGCAR2_ints_2), len(CHGCAR3_ints_3)) ) : f.write(str(CHGCAR1_ints_1[i] - CHGCAR2_ints_2[i] - CHGCAR3_ints_3[i])) f.write(' ') print(f)
修复方案
问题根源
代码硬编码了CHGCAR1、CHGCAR2、CHGCAR3固定文件名,但GUI中用户选择的文件路径并未传递到charge_density函数,导致程序在当前工作目录中查找不存在的固定名称文件,触发报错。
具体调整步骤
- 修改函数参数,接收用户选择的文件路径
让charge_density函数通过参数获取实际文件路径,而非依赖固定文件名。 - 完善GUI文件选择逻辑
在GUI中添加文件选择功能,保存用户选中的三个文件路径,点击计算按钮时传递给函数。 - 优化代码结构与逻辑
封装重复的文件读取逻辑,修复原代码中输出文件的缩进错误(原代码仅在循环结束后写入一个空格)。
调整后的示例代码
import tkinter as tk from tkinter import filedialog, messagebox # 存储用户选择的三个文件路径 selected_files = [] def select_three_files(): global selected_files # 弹出文件选择框,允许选择多个文件 selected_files = filedialog.askopenfilenames( title="选择三个CHGCAR文件", filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")] ) # 校验选择的文件数量 if len(selected_files) != 3: messagebox.showwarning("提示", "请选择恰好三个文件!") selected_files = [] def safeFloat(x): try: return float(x) except ValueError: return None def read_and_parse_file(file_path): """封装文件读取与数值解析逻辑""" with open(file_path, 'r', encoding='utf-8') as f: content = f.read() # 转换为数值列表并过滤无效值 num_list = [safeFloat(item) for item in content.split()] return [num for num in num_list if num is not None] def charge_density(file1, file2, file3): # 读取并解析三个文件 list1 = read_and_parse_file(file1) list2 = read_and_parse_file(file2) list3 = read_and_parse_file(file3) # 取最小长度避免索引越界 min_length = min(len(list1), len(list2), len(list3)) # 写入计算结果 with open("CHGCAR_final.txt", 'w', encoding='utf-8') as f: for i in range(min_length): result = list1[i] - list2[i] - list3[i] f.write(f"{result} ") print("计算完成,结果已保存至CHGCAR_final.txt") # 构建GUI界面 root = tk.Tk() root.title("电荷密度计算工具") # 文件选择按钮 select_btn = tk.Button(root, text="选择三个文件", command=select_three_files) select_btn.pack(pady=15) # 计算按钮 calc_btn = tk.Button( root, text="执行数值相减", command=lambda: charge_density(*selected_files) if len(selected_files)==3 else messagebox.showwarning("提示", "请先选择三个文件!") ) calc_btn.pack(pady=15) root.mainloop()
关键说明
- 函数
charge_density通过参数接收用户选择的实际文件路径,彻底解决文件找不到的问题。 - 新增
read_and_parse_file辅助函数,复用文件读取与数值转换逻辑,简化代码结构。 - 修复原代码中
f.write(' ')的缩进错误,确保每个计算结果后都添加空格。 - 添加文件数量校验,避免用户未选够文件时执行计算。
内容的提问来源于stack exchange,提问作者msut akdss
相关产品推荐
相关产品推荐

