вызов функции с динамическим именем объекта pyqt5

Извините за приведенную выше формулировку вопроса, не ясно, я не знаю точно, как ее сформулировать.

Мой запрос: у меня есть кнопки, которые имеют одинаковую функциональность, но они повторяются. Следовательно, я хочу изменить код, поэтому я хочу вызвать функцию с именем объекта и получить значения / выполнить любую операцию с этим объектом.

Вот пример кода.

      self.movement('intro_files_paths',final_intro_list)

движение - это функция, которую я хочу вызвать для определенной функциональности intro_files_paths - это имя объекта элемента pyqt5 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

все ниже находится в том же классе

Полный код

      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>

3 ответа

Решение

в movement функция у вас есть аргумент, но вы пытаетесь получить доступ self.b. Ошибка довольно очевидна: нет b ни в вашем пользовательском интерфейсе, ни в вашем экземпляре, но даже если бы это было так, это не имеет большого смысла, поскольку вы хотите использовать аргумент функции.

Поскольку эти функции уже относятся к реальным объектам, действительно нет смысла пытаться получить доступ к атрибутам как к строкам, просто используйте атрибут:

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

    def movement(self, a, b, c):
        index = 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» бессмысленно, это не дает никаких преимуществ и делает ваш код только более трудным для чтения (даже для вас); подробнее о предлагаемой практике читайте в официальном Руководстве по стилю кода Python.
Наконец, всегда не рекомендуется использовать глобальные переменные; эмпирическое правило: вы должны использовать их только в том случае, если вы действительно знаете, почему они должны использоваться, и если вы знаете, почему они должны использоваться, то вы, вероятно, не будете их использовать. Вместо этого используйте атрибуты экземпляра.

Вместо self.bпросто делай self или же bпотому что это параметры функции. Какой из них вы используете, зависит от того, с каким объектом вы работаете.

Вы проходите b в функции, когда вы используете self.b в функции.

Другие вопросы по тегам