вызов функции с динамическим именем объекта 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
в функции.