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

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_()

关键改动说明

  1. 替换全局变量为实例变量:把final_intro_list改成self.final_intro_list,摆脱对全局变量的依赖,代码更健壮,也方便后续扩展多个列表的操作场景。
  2. 用getattr()获取组件:list_widget = getattr(self, widget_name)会根据传入的字符串(比如'intro_files_paths')获取UI类中对应的QListWidget组件,完美解决了原来的属性访问错误。
  3. 添加边界检查:增加了未选中项、上移到顶部、下移到底部的判断,避免用户误操作时出现索引越界崩溃。
  4. 简化按钮绑定:用lambda直接把参数传给movement函数,省去了中间的move_up_in_list_4这类冗余封装函数,让代码更简洁。

这样修改后,你的复用逻辑就能正常工作了,代码结构也更清晰易维护。

内容的提问来源于stack exchange,提问作者Eswar T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 14:27:46