PyQt5中传入动态对象名调用函数时出现AttributeError的问题解决
解决PyQt5中通过组件对象名复用列表操作函数的AttributeError问题
我明白你遇到的问题了——你想通过传入组件对象名来复用movement函数,减少重复代码,但因为直接用self.b访问组件(而b是字符串),导致了AttributeError: 'UI' object has no attribute 'b'的错误。这是因为Python不知道你要的是名字等于b字符串的属性,而是直接去找名为b的属性,显然你的UI类里没有这个属性。
核心解决思路
要根据字符串获取对应的组件实例,你可以用Python内置的getattr()函数,它能根据属性名字符串获取对象的属性值。另外,建议把全局列表改成类的实例变量,避免使用global,更符合面向对象的设计。
修改后的完整代码
from PyQt5 import QtWidgets from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QTextEdit, QFileDialog from PyQt5 import uic import sys class UI(QMainWindow): def __init__(self): super(UI, self).__init__() uic.loadUi("lol.ui", self) # 把全局列表改成实例变量,避免使用global self.final_intro_list = ['C:/Users/thota/OneDrive/Desktop/VET/testing area/1.mp4', 'C:/Users/thota/OneDrive/Desktop/VET/testing area/2.mp4', 'C:/Users/thota/OneDrive/Desktop/VET/testing area/30sec.mp4', 'C:/Users/thota/OneDrive/Desktop/VET/testing area/1280.mp4', 'C:/Users/thota/OneDrive/Desktop/VET/testing area/12800.mp4', 'C:/Users/thota/OneDrive/Desktop/VET/testing area/out.mp4', 'C:/Users/thota/OneDrive/Desktop/VET/testing area/output.mp4'] self.show() # 用lambda直接绑定参数,省去中间封装函数 self.move_up_4.clicked.connect(lambda: self.movement(0, 'intro_files_paths', self.final_intro_list)) self.move_down_4.clicked.connect(lambda: self.movement(1, 'intro_files_paths', self.final_intro_list)) self.remove_4.clicked.connect(lambda: self.movement(2, 'intro_files_paths', self.final_intro_list)) # 初始化列表内容 for i in self.final_intro_list: self.intro_files_paths.addItem(i) def movement(self, action_type, widget_name, data_list): # 根据组件名字符串获取对应的QListWidget实例 list_widget = getattr(self, widget_name) index = list_widget.currentRow() # 处理边界情况:没有选中项时直接返回 if index == -1: return if action_type == 0: # 上移 if index > 0: self.swapPositions(data_list, index, index-1) elif action_type == 1: # 下移 if index < len(data_list)-1: self.swapPositions(data_list, index, index+1) else: # 删除 del data_list[index] # 更新列表组件显示 list_widget.clear() for item in data_list: list_widget.addItem(item) def swapPositions(self, lst, pos1, pos2): lst[pos1], lst[pos2] = lst[pos2], lst[pos1] app = QApplication(sys.argv) window = UI() app.exec_()
关键改动说明
- 替换全局变量为实例变量:把
final_intro_list改成self.final_intro_list,摆脱对全局变量的依赖,代码更健壮,也方便后续扩展多个列表的操作场景。 - 用
getattr()获取组件:list_widget = getattr(self, widget_name)会根据传入的字符串(比如'intro_files_paths')获取UI类中对应的QListWidget组件,完美解决了原来的属性访问错误。 - 添加边界检查:增加了未选中项、上移到顶部、下移到底部的判断,避免用户误操作时出现索引越界崩溃。
- 简化按钮绑定:用
lambda直接把参数传给movement函数,省去了中间的move_up_in_list_4这类冗余封装函数,让代码更简洁。
这样修改后,你的复用逻辑就能正常工作了,代码结构也更清晰易维护。
内容的提问来源于stack exchange,提问作者Eswar T
相关产品推荐
相关产品推荐

