PyQt5循环动态添加Widget后交互触发NameError问题求助
问题分析与解决方案
错误原因
你遇到的NameError: name 'recup_fichiers_selec' is not defined,大概率是代码执行顺序异常(比如函数定义写在了connect语句之后)或函数缩进错误导致未被正确识别。从你提供的代码来看,函数定义顺序是正确的,但代码存在全局变量滥用和冗余的globals()操作,会引发更多潜在问题。
修正方案
通过以下方式优化代码,彻底解决当前错误并提升可维护性:
- 移除不必要的
globals()操作,直接用字典存储动态创建的CheckBox - 避免过度依赖全局变量,用类封装所有逻辑(符合PyQt编程规范)
- 修复
recup_fichiers_selec中错误的CheckBox状态判断逻辑(原代码错误调用了dlg.checkb.isTristate(),应判断当前循环的CheckBox是否选中)
修正后的完整代码
from PyQt5.QtWidgets import QApplication, QWidget, QCheckBox from PyQt5 import uic import sys import glob import os from pathlib import Path class MainWindow: def __init__(self): self.dlg = uic.loadUi("logiciel_Rint3.ui") # 初始化存储CheckBox的字典和文件列表 self.var_checkd = {} self.var_checkr = {} self.L_file_direct = [] self.L_file_reflechi = [] # 绑定按钮事件 self.dlg.pushb_ini.clicked.connect(self.charger_fichiers) self.dlg.pushb_freflechis.clicked.connect(self.recup_fichiers_selec) def charger_fichiers(self): nom_cristal = "SiTrans" date = "2022-05-06" # 处理direct目录下的文件 directory = f'C:/Users/diops/Desktop/Programme Rint_numérique/dépouillement/{nom_cristal}/{date}/direct' os.chdir(directory) c_d = 1 for file in glob.glob("*.tif"): checkb = QCheckBox() self.var_checkd[c_d] = checkb self.dlg.formLayout_direct.addRow(Path(file).stem, checkb) self.L_file_direct.append(Path(file).stem) c_d += 1 # 处理reflechi目录下的文件 directory = f'C:/Users/diops/Desktop/Programme Rint_numérique/dépouillement/{nom_cristal}/{date}/reflechi' os.chdir(directory) c_r = 1 for file in glob.glob("*.tif"): checkb = QCheckBox() self.var_checkr[c_r] = checkb self.dlg.formLayout_reflechi.addRow(Path(file).stem, checkb) self.L_file_reflechi.append(Path(file).stem) c_r += 1 def recup_fichiers_selec(self): # 获取direct目录下选中的文件 for idx in self.var_checkd: checkb = self.var_checkd[idx] if checkb.isChecked(): print(f"选中的direct文件: {self.L_file_direct[idx-1]}") # 获取reflechi目录下选中的文件 for idx in self.var_checkr: checkb = self.var_checkr[idx] if checkb.isChecked(): print(f"选中的reflechi文件: {self.L_file_reflechi[idx-1]}") if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.dlg.show() sys.exit(app.exec())
关键优化点说明
- 用类封装所有逻辑,避免全局变量导致的作用域混乱
- 直接通过字典存储动态创建的CheckBox,无需
globals()生成全局变量,代码更安全 - 修复状态判断逻辑:改为判断当前循环的CheckBox是否被选中
- 使用f-string拼接路径,代码更简洁易读
- 移除冗余的模块重复导入
内容的提问来源于stack exchange,提问作者Sidy
相关产品推荐
相关产品推荐

