使用动态对象名 pyqt5 调用函数

calling a function with dynamic objectname pyqt5

抱歉上面的问题表述不清楚,我不知道具体应该怎么表述。

我的查询是我有一些按钮具有相同的功能但它们是重复的因此我想修改代码所以我想用对象名称调用函数并获取值/对该对象执行任何操作

这是示例代码。

self.movement('intro_files_paths',final_intro_list)

movement 是我想为特定功能调用的函数 intro_files_paths是pyqt5 item Widget的对象名

而移动的功能是这样的

def movement(self,b,c):

    index=self.b.currentRow()

    c=self.swapPositions(c,index,index-1)

    self.b.clear()

    for i in c:
        self.b.addItem(i)

所以我得到了错误

AttributeError: 'UI' object has no attribute 'b'

我明白为什么我会收到错误 但是不知道如何解决这个问题

更多信息: 我正在构建一个视频编辑应用程序,我正在尝试进行批量视频编辑。因此,当有人打开一个文件时,文件名存储在一个列表中,并按照他们打开它们的顺序显示在 qt 列表小部件中,因此在打开它们之后,用户可能想要更改视频的顺序因此我给 move_up move_down 和 delete_item

下面的都是一样的class

完整代码

from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QTextEdit, QFileDialog
from PyQt5 import uic
import sys

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']

class UI(QMainWindow):
    def __init__(self):
        super(UI, self).__init__()
        uic.loadUi("lol.ui", self)

        self.show()

        self.move_up_4.clicked.connect(self.move_up_in_list_4)
        self.move_down_4.clicked.connect(self.move_down_in_list_4)
        self.remove_4.clicked.connect(self.remove_in_list_4)
        for i in final_intro_list:
            self.intro_files_paths.addItem(i)

    def move_up_in_list_4(self):
        global final_intro_list
        self.movement(0,'intro_files_paths',final_intro_list)

    def move_down_in_list_4(self):
        global final_intro_list
        self.movement(1,'intro_files_paths',final_intro_list)

    def remove_in_list_4(self):
        global final_intro_list
        self.movement(2,'intro_files_paths',final_intro_list)

    def movement(self,a,b,c):
        index=self.b.currentRow()
        if(a==0): #moving up in list
            c=self.swapPositions(c,index,index-1)
        elif(a==1): #moving down in list
            c=self.swapPositions(c,index,index+1)
        else: # delete that item
            del c[index]
        self.b.clear()
        for i in c:
            self.b.addItem(i)

    def swapPositions(self,list, pos1, pos2):
         list[pos1], list[pos2] = list[pos2], list[pos1]
         return list


app = QApplication(sys.argv)
window = UI()
app.exec_()

GUI 代码

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>811</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QListWidget" name="intro_files_paths">
    <property name="geometry">
     <rect>
      <x>100</x>
      <y>90</y>
      <width>430</width>
      <height>290</height>
     </rect>
    </property>
    <property name="dragDropMode">
     <enum>QAbstractItemView::DragDrop</enum>
    </property>
    <property name="movement">
     <enum>QListView::Free</enum>
    </property>
    <property name="spacing">
     <number>0</number>
    </property>
    <property name="gridSize">
     <size>
      <width>20</width>
      <height>20</height>
     </size>
    </property>
    <property name="viewMode">
     <enum>QListView::ListMode</enum>
    </property>
   </widget>
   <widget class="QPushButton" name="remove_4">
    <property name="geometry">
     <rect>
      <x>540</x>
      <y>270</y>
      <width>41</width>
      <height>41</height>
     </rect>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="icon">
     <iconset>
      <normaloff>Cross.png</normaloff>Cross.png</iconset>
    </property>
    <property name="iconSize">
     <size>
      <width>50</width>
      <height>50</height>
     </size>
    </property>
   </widget>
   <widget class="QPushButton" name="move_up_4">
    <property name="geometry">
     <rect>
      <x>540</x>
      <y>170</y>
      <width>41</width>
      <height>41</height>
     </rect>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="icon">
     <iconset>
      <normaloff>up.png</normaloff>up.png</iconset>
    </property>
    <property name="iconSize">
     <size>
      <width>50</width>
      <height>50</height>
     </size>
    </property>
   </widget>
   <widget class="QPushButton" name="move_down_4">
    <property name="geometry">
     <rect>
      <x>540</x>
      <y>220</y>
      <width>41</width>
      <height>41</height>
     </rect>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="icon">
     <iconset>
      <normaloff>down.png</normaloff>down.png</iconset>
    </property>
    <property name="iconSize">
     <size>
      <width>50</width>
      <height>50</height>
     </size>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

而不是 self.b,只需执行 selfb,因为这些是函数的参数。你用哪个取决于你在哪个对象上操作。

您在函数中传递 b 而在函数中使用 self.b

movement 函数中,您有一个 b 参数,但您正在尝试访问 self.b。错误很明显:您的 UI 中没有 b 对象,您的实例中也没有,但即使有,也没有多大意义,因为您想使用参数功能。

由于这些函数已经引用了实际对象,因此尝试以字符串形式访问属性真的没有意义,只需使用属性:

    def remove_in_list_4(self):
        global final_intro_list
        self.movement(2, <b>self.intro_files_paths</b>, final_intro_list)

    def movement(self, a, b, c):
        index = <b>b</b>.currentRow()

为了知识,您可以使用字符串文字来访问实例属性:

        # ...
        self.movement(2, 'intro_files_paths', final_intro_list)

    def movement(self, a, b, c):
        index = getattr(self, b).currentRow()

对于 Qt 对象也是如此:

    def movement(self, a, b, c):
        index = self.findChild(QListWidget, b).currentRow()

但是,如前所述,仅应在特定情况下使用名称属性(例如,由于配置文件解析而动态创建的对象)。对于任何其他情况,它通常不是必需的,它通常是实施不当的症状。

无论如何,我强烈建议你对 类 和实例(它们是什么,它们是如何工作的)做更多的研究和研究,并认真改进你的语法和命名:将变量命名为“ a, b, c" 是没有意义的,它没有任何好处,只会让你的代码更难阅读(甚至对你来说也是如此);在官方 Style Guide for Python Code.
上阅读更多关于建议的做法 最后,总是不鼓励使用全局变量。经验法则是:只有当你真正知道为什么要使用它们时才应该使用它们,如果你知道为什么要使用它们,那么你可能不会使用它们。请改用实例属性。