@ToxaDHD

Как правильно придать функционал кнопкам в PyQt5?

Здравствуйте. Я пишу программу с использованием библиотеки PyQt5 и у меня возникла такая проблема:

На главном окне у меня расположены кнопки. Со временем количество этих кнопок может измениться, поэтому все объекты кнопок я решил сохранить в список и обходить его циклом for, поочерёдно присваивая им функционал. В результате я получаю то, что у всех кнопок функционал, который должен быть у последней кнопки.

Чтобы не заставлять никого перечитывать сотни строк кода, ниже я привожу сильно упрощенный вариант моей программы, но от этого суть проблемы не меняется.

from PyQt5 import QtCore, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(316, 142)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.btn1 = QtWidgets.QPushButton(self.centralwidget)
        self.btn1.setObjectName("btn1")
        self.verticalLayout.addWidget(self.btn1)
        self.btn2 = QtWidgets.QPushButton(self.centralwidget)
        self.btn2.setObjectName("btn2")
        self.verticalLayout.addWidget(self.btn2)
        self.btn3 = QtWidgets.QPushButton(self.centralwidget)
        self.btn3.setObjectName("btn3")
        self.verticalLayout.addWidget(self.btn3)
        MainWindow.setCentralWidget(self.centralwidget)

        self.btns = [self.btn1, self.btn2, self.btn3]
        self.add_functions_to_buttons()

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def add_functions_to_buttons(self):
        for n in range(len(self.btns)):
            self.btns[n].clicked.connect(lambda: print(n + 1))

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.btn1.setText(_translate("MainWindow", "Первая кнопка"))
        self.btn2.setText(_translate("MainWindow", "Вторая кнопка"))
        self.btn3.setText(_translate("MainWindow", "Третья кнопка"))


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Почему у всех кнопок одинаковый функционал я уже понял. Сейчас я хочу понять, как можно добиться того результата, который мне нужен.
  • Вопрос задан
  • 475 просмотров
Решения вопроса 2
sergey-gornostaev
@sergey-gornostaev Куратор тега Python
Седой и строгий
@ToxaDHD Автор вопроса
Методом проб и ошибок удалось решить проблему. Большое спасибо Сергею, за то что натолкнул на правильную мысль.

Мне действительно следовало использовать замыкание в lambda-функции, в последствии это помогло получить необходимый результат.

Сергей подсказал мне, что проблема заключается в методе .clicked(). Я не смог в нём разобраться. Не смог понять, как его правильно использовать в моей ситуации, поэтому решил не использовать его вообще, а вместо этого заменить его методом .released(), который срабатывает в момент отпускания кнопки. После передачи lambda-функции с замыканием в него, всё заработало так, как я и хотел.

В результате функция выглядит так:
def add_functions_to_buttons(self):
        for n in range(len(self.btns)):
            self.btns[n].released.connect(lambda x=n: print(x+1))
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

Похожие вопросы