Иногда вам нужно, чтобы несколько кнопок вызывали один и тот же хэндлер событий. Обычно это происходит если у вас в программе несколько кнопок со схожими задачами. В некоторых случаях стоит привязать и кнопку закрытия окна, и итем закрытия окна в меню к одному и тому же хэндлеру событий, чтобы не писать разные фрагменты кода для выполнения одинаковых задач. Для этого нужно ознакомиться с принципом Don’t Repeat Yourself (DRY), что переводится как «Не повторяй себя».
Приступая к работе

Для начала напишем код, содержащий несколько кнопок. Я продемонстрирую вам пример, отображающий два разных способа того, как добиться от кнопки выполнения поставленной задачи, так что вы научитесь универсальному применению метода. Вот код, которого вы так сильно ждали:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
import wx class MyForm(wx.Frame): def __init__(self): wx.Frame.__init__( self, None, title="Binding Multiple Widgets") panel = wx.Panel(self, wx.ID_ANY) sizer = wx.BoxSizer(wx.VERTICAL) buttonOne = wx.Button(panel, label="One", name="one") buttonTwo = wx.Button(panel, label="Two", name="two") buttonThree = wx.Button(panel, label="Three", name="three") buttons = [buttonOne, buttonTwo, buttonThree] for button in buttons: self.buildButtons(button, sizer) panel.SetSizer(sizer) def buildButtons(self, btn, sizer): """""" btn.Bind(wx.EVT_BUTTON, self.onButton) sizer.Add(btn, 0, wx.ALL, 5) def onButton(self, event): """ Данный метод запускается, когда нажат соответствующая кнопка. """ button = event.GetEventObject() print("The button you pressed was labeled: " + button.GetLabel()) print("The button's name is " + button.GetName()) button_id = event.GetId() button_by_id = self.FindWindowById(button_id) print("The button you pressed was labeled: " + button_by_id.GetLabel()) print("The button's name is " + button_by_id.GetName()) if __name__ == "__main__": app = wx.App(False) frame = MyForm() frame.Show() app.MainLoop() |
Сначала мы создаём 3 объекта кнопок. Чтобы избавится от лишней суеты, мы сразу помещаем их в список, а затем повторяем внутри списка, чтобы добавить кнопки в сайзер и привязать их к хэндлеру событий. Это отличный способ сокращения скопированного и вставленного кода, ведь так он выглядит чище и в нём проще искать баги. Иногда люди на этом не останавливаются и применяют сложные продуманные вспомогательные методы вроде buildButtons, ведь он может работать со многими виджетами, что делает программирование более гибким.
Часть, на которую нам стоит обратить внимание – это сам хэндлер событий. Самый простой способ поместить виджет в хэндлер событий называется методом GetEventObject. Он вернёт виджет и вы сможете делать всё, что захотите. Некоторые люди меняют значение или ярлык виджета, другие используют ID виджета или уникальное имя и добавляют различные условные структуры, которые запускают определённое действие при нажатии кнопки. То есть функциональность полностью зависит исключительно от вас.
Второй способ получить виджет – двухэтапный процесс, в рамках которого нам нужно сначала извлечь ID из события используя метод GetID(). Затем же мы передаём результаты в наш объект фрейма, используя метод FindWindowById() и мы снова have the widget in question
Итоги
Теперь вы знакомы с «секретом» прикрепления нескольких виджетов к одному и тому же хэндлеру событий. Всё, что вам нужно знать: если вы пишите 2 функции, выполняющие одну и ту же задачу, или копируете и вставляете функцию, совершая лишь минимальные изменения, вам нужно провести рефакторинг вашего кода, чтобы избежать проблем в будущем.

Являюсь администратором нескольких порталов по обучению языков программирования Python, Golang и Kotlin. В составе небольшой команды единомышленников, мы занимаемся популяризацией языков программирования на русскоязычную аудиторию. Большая часть статей была адаптирована нами на русский язык и распространяется бесплатно.
E-mail: vasile.buldumac@ati.utm.md
Образование
Universitatea Tehnică a Moldovei (utm.md)
- 2014 — 2018 Технический Университет Молдовы, ИТ-Инженер. Тема дипломной работы «Автоматизация покупки и продажи криптовалюты используя технический анализ»
- 2018 — 2020 Технический Университет Молдовы, Магистр, Магистерская диссертация «Идентификация человека в киберпространстве по фотографии лица»