@ITemka

Как к каждой кнопке в PyQt5 динамически привязать собственную функцию, чтобы каждая кнопка выполняла свое действие?

Пишу десктоп-программу на Python PyQt5, суть которой спарсить видео с YouTube-плейлиста по ключевым словам. Результаты передаются в список, и далее через цикл for я прохожусь по нему, для каждого результата (строки, в которой содержится информация о найденном по ключевому слову видео - его название и ссылка на него) я создаю свою кнопку, нажав на которую с помощью библиотеки pyperclip ссылка на нужное видео кладется в буфер обмена компьютера.

Проблема состоит в том, что в зависимости от количества найденных в плейлисте видео, кнопок создается порой очень много, но при этом для системы все они - это одна и та же кнопка, ссылающаяся на САМОЕ ПОСЛЕДНЕЕ видео, найденное в плейлисте.

Пример:
Предположим, что спарсилось 10 видео, у каждого из которых название соответствует его порядковому номеру: видео_1, видео_2, видео_3 и т.д. до видео_10. Под каждым названием появляется своя собственная кнопка. Я хочу получить ссылку на видео_4, нажимаю на кнопку, а копируется ссылка на видео_10. И на какую бы кнопку я не нажал, всегда копируется ссылка на видео_10.

Я так понимаю, проблема в том, что для всех кнопок (а я ведь не могу знать, сколько каждый раз их появится) у меня прописана одна функция-обработчик, которая все эти кнопки видит как одну и ту же (как в моем примере - все кнопки она видит как самую последнюю кнопку для видео_10, вот и копирует ссылку именно на него). Следовательно, необходимо динамически добавлять для каждой кнопки собственную функцию, чтобы каждая кнопка позиционировалась как отдельная, уникальная. Но как это сделать, не знаю. Бьюсь над проблемой очень много. Надеюсь, сможете помочь)

Скрин окна (в качестве примера был взят плейлист с прохождением игры Atomic Heart в исполнении моего любимого блогера):
64296b6de3f0c517054521.jpeg

Также мой код, отвечающий за все вышеперечисленное:

def search_videos(playlist_url, keyword): # function to parse a playlist (with help pytube)
	try: # try/except becose pytube have a promlems sometimes
		playlist = Playlist(playlist_url)
		for video in playlist.videos:
			if keyword in video.title:
				results_list.append(f'{video.title}  -  https://www.youtube.com/watch?v={video.video_id}')
				print(f'{video.title}  -  https://www.youtube.com/watch?v={video.video_id}')
		sort_results(results_list, Dialog, ui)
	except Exception as ex:
		print(ex)
		sort_results(results_list, Dialog, ui)

def sort_results(list_, Dialog, ui): # function gets list with results from search_videos and works with them further
	for video in list_:
		global copyURL_height
		ui.copyURL = QtWidgets.QPushButton(Dialog) # video button
		ui.copyURL.setText('Скопировать ссылку')
		ui.copyURL.setGeometry(copyURL_width, copyURL_height, copyURL_width_2, copyURL_height_2)
		ui.copyURL.show()
		URL = video.split('  -  ')[-1]
		ui.copyURL.clicked.connect(lambda: pyperclip.copy(URL))   # lambda-function that allows to copy the URL of the video
		copyURL_height += 68
  • Вопрос задан
  • 503 просмотра
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега PyQt
Седой и строгий
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@ITemka Автор вопроса
БлагоДарю! Все ПОЛУЧИЛОСЬ!!!
Кому интересно, проблема была в lambda-функции, которая при нажатии на любую кнопку ссылалась на самый последний объект. Для избежания этого достаточно замкнуть lambda:

Вместо:

ui.copyURL.released.connect(lambda: pyperclip.copy(URL))


Сделать так:

ui.copyURL.released.connect(lambda URL = URL: pyperclip.copy(URL))
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы