Лучший способ получить название кнопки, которая называется событием?

В следующем коде (вдохновленном этим фрагментом) я использую один обработчик события buttonClick чтобы изменить заголовок окна. В настоящее время мне нужно оценить, соответствует ли Id события идентификатору кнопки. Если я решил добавить 50 кнопок вместо 2, этот метод может стать громоздким. Есть лучший способ сделать это?

 import wx class MyFrame(wx.Frame): def __init__(self): wx.Frame.__init__(self, None, wx.ID_ANY, 'wxBitmapButton', pos=(300, 150), size=(300, 350)) self.panel1 = wx.Panel(self, -1) self.button1 = wx.Button(self.panel1, id=-1, pos=(10, 20), size = (20,20)) self.button1.Bind(wx.EVT_BUTTON, self.buttonClick) self.button2 = wx.Button(self.panel1, id=-1, pos=(40, 20), size = (20,20)) self.button2.Bind(wx.EVT_BUTTON, self.buttonClick) self.Show(True) def buttonClick(self,event): if event.Id == self.button1.Id: self.SetTitle("Button 1 clicked") elif event.Id == self.button2.Id: self.SetTitle("Button 2 clicked") application = wx.PySimpleApp() window = MyFrame() application.MainLoop() 

7 Solutions collect form web for “Лучший способ получить название кнопки, которая называется событием?”

Вы можете дать кнопке имя, а затем посмотреть имя в обработчике событий.

Когда вы делаете кнопку

 b = wx.Button(self, 10, "Default Button", (20, 20)) b.myname = "default button" self.Bind(wx.EVT_BUTTON, self.OnClick, b) 

При нажатии кнопки:

 def OnClick(self, event): name = event.GetEventObject().myname 

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

 import functools def __init__(self): # ... for i in range(10): name = 'Button %d' % i button = wx.Button(parent, -1, name) func = functools.partial(self.on_button, name=name) button.Bind(wx.EVT_BUTTON, func) # ... def on_button(self, event, name): print '%s clicked' % name 

Конечно, аргументы могут быть любыми, что вы хотите.

Я рекомендую использовать разные обработчики событий для обработки событий с каждой кнопки. Если есть много общего, вы можете объединить это в функцию, которая возвращает функцию с конкретным поведением, которое вы хотите, например:

 def goingTo(self, where): def goingToHandler(event): self.SetTitle("I'm going to " + where) return goingToHandler def __init__(self): buttonA.Bind(wx.EVT_BUTTON, self.goingTo("work")) # clicking will say "I'm going to work" buttonB.Bind(wx.EVT_BUTTON, self.goingTo("home")) # clicking will say "I'm going to home" 

Храните dict с ключами, которые являются .Id кнопок и значений, которые являются именами кнопок или что-то еще, поэтому вместо длинной цепочки if/elif вы делаете один поиск в dict в buttonClick .

Фрагменты кода: в __init__ добавьте создание и обновление dict :

 self.panel1 = wx.Panel(self, -1) self.thebuttons = dict() self.button1 = wx.Button(self.panel1, id=-1, pos=(10, 20), size = (20,20)) self.thebuttons[self.button1.Id] = 'Button 1' self.button1.Bind(wx.EVT_BUTTON, self.buttonClick) 

и т. д. для 50 кнопок (или что-то еще) [они могут быть лучше созданы в цикле, btw ;-)]. Таким образом, buttonClick становится:

  def buttonClick(self,event): button_name = self.thebuttons.get(event.Id, '?No button?') self.setTitle(button_name + ' clicked') 

Вы можете создать словарь кнопок и сделать вид на основе id … что-то вроде этого:

 class MyFrame(wx.Frame): def _add_button (self, *args): btn = wx.Button (*args) btn.Bind (wx.EVT_BUTTON, self.buttonClick) self.buttons[btn.id] = btn def __init__ (self): self.button = dict () self._add_button (self.panel1, id=-1, pos=(10, 20), size = (20,20)) self._add_button = (self.panel1, id=-1, pos=(40, 20), size = (20,20)) self.Show (True) def buttonClick(self,event): self.SetTitle (self.buttons[event.Id].label) 

У меня возникла аналогичная проблема: я генерировал кнопки на основе данных, предоставленных пользователем, и мне нужны кнопки для воздействия на другой класс, поэтому мне нужно было передать информацию о кнопке buttonclick. То, что я сделал, явным образом назначало идентификаторы кнопок каждой созданной кнопке, а затем сохраняла информацию о них в словаре для поиска позже.

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

Вот немного скрабленный пример кода чего-то подобного:

 self.buttonDefs = {} self.buttons = [] id_increment = 800 if (row, col) in self.items: for ev in self.items[(row, col)]: id_increment += 1 #### Populate a dict with the event information self.buttonDefs[id_increment ] = (row, col, ev['user']) #### tempBtn = wx.Button(self.sidebar, id_increment , "Choose", (0,50+len(self.buttons)*40), (50,20) ) self.sidebar.Bind(wx.EVT_BUTTON, self.OnShiftClick, tempBtn) self.buttons.append(tempBtn) def OnShiftClick(self, evt): ### Lookup the information from the dict row, col, user = self.buttonDefs[evt.GetId()] self.WriteToCell(row, col, user) self.DrawShiftPicker(row, col) 

Мне нужно было сделать то же самое, чтобы следить за нажатием кнопки. Я использовал функцию лямбда для привязки к событию. Таким образом, я мог бы передать весь объект кнопки в функцию обработчика событий, чтобы манипулировать соответствующим образом.

  class PlatGridderTop(wx.Frame): numbuttons = 0 buttonlist = [] def create_another_button(self, event): # wxGlade: PlateGridderTop.<event_handler> buttoncreator_id = wx.ID_ANY butonname = "button" + str(buttoncreator_id) PlateGridderTop.numbuttons = PlateGridderTop.numbuttons + 1 thisbutton_number = PlateGridderTop.numbuttons self.buttonname = wx.Button(self,buttoncreator_id ,"ChildButton %s" % thisbutton_number ) self.Bind(wx.EVT_BUTTON,lambda event, buttonpressed=self.buttonname: self.print_button_press(event,buttonpressed),self.buttonname) self.buttonlist.append(self.buttonname) self.__do_layout() print "Clicked plate button %s" % butonname event.Skip() def print_button_press(self,event,clickerbutton): """Just a dummy method that responds to a button press""" print "Clicked a created button named %s with wxpython ID %s" % (clickerbutton.GetLabel(),event.GetId()) 

Отказ от ответственности: Это мое первое сообщение в stackoverflow

  • Проблемы с Py2exe lxml
  • Как изменить имя приложения в строке меню OSX в наборе приложений с чистым Python?
  • Альтернативная раскраска строк в Scintilla
  • Как вы принудительно обновляете wx.Panel?
  • wxPython / ReportLab: как создать и открыть файл .pdf при нажатии кнопки
  • Значок wxpython для панели задач
  • wxPython не будет закрывать Frame с родителем, который является дескриптором окна
  • Быстро и просто: лоток с питоном?
  • Python - лучший язык программирования в мире.