PyQt程序QListWidget为空时报NameError,如何跳过空列表正常运行
问题解决方案
问题根源
- 你用到的
team_biz/team_ath/team_env都是全局变量,只有触发对应分类的右移按钮时才会被定义,如果某类从来没添加过文件,这个变量就不存在,遍历的时候就会触发NameError - 左移文件回总列表时没有同步更新对应的路径列表,会出现列表控件内容和路径列表不一致的问题
- 全局变量本身不符合PyQt类封装的规范,容易出现变量生命周期问题
最优改造方案
将全局变量替换为类实例属性,同步列表控件和路径列表的内容,遍历前判断是否有文件再执行:
第一步:初始化实例属性,删掉所有全局变量声明
修改__init__方法:
def __init__(self): super().__init__() self.setupUi(self) # 新增初始化三个分类路径列表和文件根路径 self.path = "" self.team_biz = [] self.team_ath = [] self.team_env = [] self.btn_open.clicked.connect(self.showDialog) self.btn_next.clicked.connect(self.result) self.item_right.clicked.connect(self.create_table) # 原有按钮绑定逻辑不变 self.left1.clicked.connect(self.clicked_left1_button) self.right1.clicked.connect(self.clicked_right1_button) self.left2.clicked.connect(self.clicked_left2_button) self.right2.clicked.connect(self.clicked_right2_button) self.left3.clicked.connect(self.clicked_left3_button) self.right3.clicked.connect(self.clicked_right3_button)
第二步:修改文件移动逻辑,每次移动后同步更新路径列表
所有右移、左移按钮方法都按这个逻辑改,这里举业务类的两个方法示例,其他两个分类同理修改:
# 业务类右移 def clicked_right1_button(self): self.move_current_item(self.listWidget, self.team_business) # 每次移动后重新生成路径列表,保证和控件内容一致 self.team_biz = [] for a in range(self.team_business.count()): text = self.team_business.item(a).text() # 用os.path.join拼接路径,避免不同系统斜杠兼容问题 dirpath = os.path.join(self.path, text) self.team_biz.append(dirpath) # 业务类左移 def clicked_left1_button(self): self.move_current_item(self.team_business, self.listWidget) # 左移后同样同步更新路径列表 self.team_biz = [] for a in range(self.team_business.count()): text = self.team_business.item(a).text() dirpath = os.path.join(self.path, text) self.team_biz.append(dirpath)
第三步:修改文件选择逻辑,路径赋值到实例属性
def showDialog(self): files = QFileDialog.getOpenFileNames(self, "파일 선택", '/', "Excel Files(*.xlsx *xls *csv)") fnames = files[0] if not fnames: return # 根路径只需要取第一个文件的目录即可,不用循环重复赋值 self.path = os.path.dirname(fnames[0]) for i in fnames: s = os.path.basename(i) self.listWidget.addItem(s)
第四步:修改create_table方法,有文件的分类才执行处理逻辑
def create_table(self): pd.options.display.float_format = '{:.5f}'.format self.AE_cor = pd.DataFrame() biz_cor = pd.DataFrame() ath_cor = pd.DataFrame() env_cor = pd.DataFrame() # 业务类有文件才处理 if self.team_biz: for i in self.team_biz: biz_team = pd.read_excel(i) # 原有业务处理逻辑保持不变 ... # 体育类有文件才处理 if self.team_ath: for i in self.team_ath: ath_team = pd.read_excel(i) # 原有业务处理逻辑保持不变 ... # 环境类有文件才处理 if self.team_env: for i in self.team_env: env_team = pd.read_excel(i) # 原有业务处理逻辑保持不变 ...
临时修复方案(不改动全局变量的情况)
如果不想大改现有代码,可以在create_table开头先判断全局变量是否存在,不存在就初始化为空列表:
def create_table(self): pd.options.display.float_format = '{:.5f}'.format global AE_cor,team_env, team_biz, team_ath # 新增变量存在性校验 for var_name in ['team_biz', 'team_ath', 'team_env']: if var_name not in globals(): globals()[var_name] = [] AE_cor = pd.DataFrame() biz_cor = pd.DataFrame() ath_cor = pd.DataFrame() env_cor = pd.DataFrame() # 遍历前先判断列表非空 if team_biz: for i in team_biz: biz_team = pd.read_excel(f'{i}') ...
内容的提问来源于stack exchange,提问作者orion62
相关产品推荐
相关产品推荐

