Best way to get the name of a button that called an event?

前端 未结 7 1174
北荒
北荒 2021-01-03 05:26

In the following code (inspired by this snippet), I use a single event handler buttonClick to change the title of the window. Currently, I need to evaluate if t

相关标签:
7条回答
  • 2021-01-03 05:46

    You could give the button a name, and then look at the name in the event handler.

    When you make the button

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

    When the button is clicked:

    def OnClick(self, event):
        name = event.GetEventObject().myname
    
    0 讨论(0)
  • 2021-01-03 05:48

    I needed to do the same thing to keep track of button-presses . I used a lambda function to bind to the event . That way I could pass in the entire button object to the event handler function to manipulate accordingly.

        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())
    

    Disclaimer : This is my first post to stackoverflow

    0 讨论(0)
  • 2021-01-03 05:52

    Keep a dict with keys that are the .Id of the buttons and values that are the button names or whatever, so instead of a long if/elif chain you do a single dict lookup in buttonClick.

    Code snippets: in __init__, add creation and update of the 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)
    

    and so on for 50 buttons (or whatever) [they might be better created in a loop, btw;-)]. So buttonClick becomes:

       def buttonClick(self,event):
           button_name = self.thebuttons.get(event.Id, '?No button?')
           self.setTitle(button_name + ' clicked')
    
    0 讨论(0)
  • 2021-01-03 05:53

    I ran into a similar problem: I was generating buttons based on user-supplied data, and I needed the buttons to affect another class, so I needed to pass along information about the buttonclick. What I did was explicitly assign button IDs to each button I generated, then stored information about them in a dictionary to lookup later.

    I would have thought there would be a prettier way to do this, constructing a custom event passing along more information, but all I've seen is the dictionary-lookup method. Also, I keep around a list of the buttons so I can erase all of them when needed.

    Here's a slightly scrubbed code sample of something similar:

    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)
    
    0 讨论(0)
  • 2021-01-03 06:07

    You could create a dictionary of buttons, and do the look based on the id ... something like this:

    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)
    
    0 讨论(0)
  • 2021-01-03 06:11

    Take advantage of what you can do in a language like Python. You can pass extra arguments to your event callback function, like so.

    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
    

    Of course, the arguments can be anything you want.

    0 讨论(0)
提交回复
热议问题