You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5循环动态添加Widget后交互触发NameError问题求助

问题分析与解决方案

错误原因

你遇到的NameError: name 'recup_fichiers_selec' is not defined,大概率是代码执行顺序异常(比如函数定义写在了connect语句之后)或函数缩进错误导致未被正确识别。从你提供的代码来看,函数定义顺序是正确的,但代码存在全局变量滥用和冗余的globals()操作,会引发更多潜在问题。

修正方案

通过以下方式优化代码,彻底解决当前错误并提升可维护性:

  1. 移除不必要的globals()操作,直接用字典存储动态创建的CheckBox
  2. 避免过度依赖全局变量,用类封装所有逻辑(符合PyQt编程规范)
  3. 修复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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 16:15:43