Главная


54.7. Трюк с дополнительными аргументами

Иногда вы хотите передать обработчику другие аргументы, кроме события.

Вот пример. Предположим, что в вашем приложении есть массив из десяти чекбоксов, виджеты которых хранятся в списке self.cbList, проиндексированном по номеру чекбоксов в range(10).

Предположим далее, что вы хотите написать один обработчик с именем .__cbHandler для событий <Button-1> во всех десяти кнопках. Обработчик может получить фактический виджет Checkbutton, который его вызвал, обратившись к атрибуту .widget передаваемого объекта Event, но как он узнает индекс этой кнопки в self.cbList?

Было бы неплохо написать наш обработчик с дополнительным аргументом для номера кнопки, что-то вроде этого:

def __cbHandler(self, event, cbNumber):

Но обработчикам событий передается только один аргумент - событие. Поэтому мы не можем использовать приведенную выше функцию из-за несоответствия количества аргументов.

К счастью, способность Python предоставлять значения по умолчанию для аргументов функции дает нам выход. Взгляните на этот код:

def __createWidgets(self):
    ...
    self.cbList = []  # Создаем список кнопок
    for i in range(10):
        cb = tk.Checkbutton(self, ...)
        self.cbList.append(cb)
        cb.grid(row=1, column=i)
        def handler(event, self=self, i=i):  # См. Сноску
            return self.__cbHandler(event, i)
        cb.bind('<Button-1>', handler)
    ...
def __cbHandler(self, event, cbNumber):
    ...

Сноска: Эти строки определяют новую функцию handler, которая ожидает три аргумента. Первый аргумент - это объект Event, передаваемый всем обработчикам событий, а второй и третий аргументы будут установлены в значения по умолчанию - дополнительные аргументы, которые нам нужно передать.

Эта техника может быть расширена для передачи обработчикам любого количества дополнительных аргументов.


>> Виртуальные события