@katavagner

Как задать событие для нескольких элементов из globals()?

Если написать следующим образом, то код замечательно работает (метод enter_course() просто выводит полученный аргумент):
globals()['btn_0'].clicked.connect(lambda: self.enter_course([1, 2, 3]))
globals()['btn_1'].clicked.connect(lambda: self.enter_course([2, 3, 4]))

т.е. при нажатии на первую кнопку выводится [1, 2, 3], а при нажатии на вторую кнопку - [2, 3, 4]. Так как кнопки генерируются автоматически, то подключить функции, выполняющиеся при нажатии на кнопку необходимо через цикл, поэтому я написал так:

i = 0
sorted_dict = {
    'a': [1, 2, 3],
    'b': [2, 3, 4]
}

for key, value in sorted_dict.items():
            globals()['btn_' + str(i)] = QPushButton( str(key.upper()), self.gridLayoutWidget)
            globals()['btn_' + str(i)].clicked.connect(lambda: self.enter_course(value))
            globals()['btn_' + str(i)].setToolTip(str(value)) # всплывающая подсказка
            i += 1

Но данный код работает не правильно. При нажатии на любую из кнопок, выводится значение, полученное последней кнопкой. При этом в всплывающей подсказке находится правильная информация. В чем может быть проблема?
  • Вопрос задан
  • 55 просмотров
Решения вопроса 1
@Taus
Описанное поведение связано с тем, как Python связывает аргументы в lambda. Вам уже написали в комментариях к вопросу, что не надо использовать globals, поэтому ориентируюсь на списки. В коде
for i in range(10):
    ...
    self.b_course[i].clicked.connect(lambda: self.enter_course(value))

значение value в lambda связывается с локальной переменной value. А поскольку она изменяется по ходу цикла, то изменяется и во всех lambda. Чтобы исправить это, нужно добавить явный аргумент в lambda:
for i in range(10):
    ...
    self.b_course[i].clicked.connect(lambda state, v=value: self.enter_course(v))

Первый аргумент state нужен, потому что clicked ещё передаёт состояние кнопки.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
от 150 000 до 200 000 ₽
OnederX Москва
от 100 000 до 120 000 ₽
Кенарий Санкт-Петербург
от 120 000 до 250 000 ₽
22 сент. 2020, в 08:35
14000 руб./за проект
22 сент. 2020, в 06:45
4000 руб./за проект
22 сент. 2020, в 03:43
35000 руб./за проект