使用Tkinter filedialog调用JSON失败,跨函数读取JSON值异常
解决JSON文件读取失败及跨函数值共享问题
核心问题根源
- 实例不独立:加载JSON和执行测量用了两个完全独立的
AcousticResponse实例,加载的JSON数据无法被测量函数访问。 - 变量引用错误:
setupSNR函数中直接使用未定义的df变量,而非类实例的self.df。 - 缺失必要依赖导入:
measurement.py未导入pandas、文件选择模块及APx相关库。 - 无异常处理:文件选择取消、JSON格式错误时会直接崩溃,没有错误提示。
修复方案及代码修改
1. 共享测量实例(修改gui.py)
在GUI类中只创建一个AcousticResponse实例,加载和测量操作共用该实例,确保JSON数据在实例内共享。
import customtkinter from customtkinter import filedialog from measurement import AcousticResponse class Myapp(): """ GUI样式设置与创建类 """ def __init__(self): self.root = customtkinter.CTk() self.root.geometry('1050x600') self.root.title("APx Platform") # 初始化全局共享的测量实例 self.measurement = AcousticResponse() # MEASUREMENT 注:需确保self.frame_2已提前定义 self.m1 = customtkinter.CTkButton(self.frame_2, text="Load JSON Script", font=("Ubuntu", 12), command=self.measurement.open_file) self.m1.grid(row=1, column=1, padx=(65, 65), pady=(5, 10)) self.m1 = customtkinter.CTkButton(self.frame_2, text="Run JSON Script", font=("Ubuntu", 12),command=self.o_and_t) self.m1.grid(row=2, column=1, padx=(50, 50), pady=(5, 10)) self.m1 = customtkinter.CTkButton(self.frame_2, text="Save Data", font=("Ubuntu", 12)) self.m1.grid(row=3, column=1, padx=(50, 50), pady=(5, 10)) def o_and_t(self): # 使用共享实例执行测量流程 self.measurement.SignalPath() self.measurement.setupSNR() app = Myapp() app.root.mainloop()
2. 修复测量模块错误(修改measurement.py)
补充依赖导入、修正变量引用、添加异常处理和字段校验,避免崩溃和数据访问错误。
import pandas as pd from customtkinter import filedialog # 请确保已导入APx相关依赖,示例: # from APx500 import APx500_Application, OutputConnectorType, InputConnectorType, MeasurandType, APxInputSelection, MeasurementType, FastFrequencyResponseSweepType class AcousticResponse(): def __init__(self): self.df = None def open_file(self): """加载测量所需的JSON配置文件""" try: filetypes = [("Json File", "*.json")] filenames = filedialog.askopenfilename(title="Open File", filetypes=filetypes) if not filenames: # 用户取消文件选择 print("未选择任何文件") return self.df = pd.read_json(filenames) print("JSON配置加载成功") except Exception as e: print(f"加载失败: {str(e)}") self.df = None def SignalPath(self): if self.df is None: print("请先加载有效的JSON配置文件") return APx = APx500_Application() APx.Visible = True APx.SignalPathSetup.OutputConnector.Type = OutputConnectorType.AnalogBalanced APx.SignalPathSetup.InputConnector.Type = InputConnectorType.AnalogBalanced APx.SignalPathSetup.Measure = MeasurandType.Acoustic input1 = APx.SignalPathSetup.InputSettings(APxInputSelection.Input1) input1.Channels[0].Name = "Mic" # 校验字段存在性,避免KeyError if "sensitivity_value_mic" in self.df and len(self.df["sensitivity_value_mic"]) > 0: input1.Channels[0].Sensitivity.Value = float(self.df["sensitivity_value_mic"][0]) else: print("JSON配置缺少sensitivity_value_mic字段或值为空") def setupSNR(self): if self.df is None: print("请先加载有效的JSON配置文件") return APx = APx500_Application() APx.AddMeasurement("Signal Path1", MeasurementType.AcousticResponse) APx.AcousticResponse.SweepType = FastFrequencyResponseSweepType.FastSweep # 修正变量引用并校验字段 if "frequency_start_value" in self.df and len(self.df["frequency_start_value"]) > 0: APx.AcousticResponse.GeneratorWithPilot.Frequencies.Start.Value = float(self.df["frequency_start_value"][0]) else: print("JSON配置缺少frequency_start_value字段或值为空")
额外优化建议
- 复用APx实例:避免在每个函数中重复创建
APx500_Application(),可在AcousticResponse的__init__中初始化一次,后续函数复用。 - GUI状态反馈:将加载成功/失败的提示显示在GUI界面上,而非仅打印到控制台。
- JSON结构预校验:加载JSON后主动校验所有必需字段,提前告知用户配置缺失问题。
内容的提问来源于stack exchange,提问作者fauzan-mhd
相关产品推荐
相关产品推荐

