On 18 Jan 2007 06:12:17 -0800, Cruelemort <[EMAIL PROTECTED]> wrote: > Hello all, > > I am new to this group (and new to Python) and was hoping someone would > be able to help me with something, it is not so much a problem it is > more of a general interest query about something i have a solution too > but am not sure it is the correct one. > > I have a class that contains a string ID and a name, and a list > containing a few objects of this type, i need to loop through this list > and create a button for each object (with the name as the label) i have > done this with the following code - > > for chan in self._channellist: > channelbutton = wx.Button(self, id=-1, > label=chan.getName()) > > channelbutton.Bind(wx.EVT_BUTTON,self._channelChanged) > > My question is this - in the _channelChanged method, how do i know > which button has been pressed when i enter the channel changed method, > and so how do i retrieve the appropriate object depending on which > button has been pressed? > > I have potentially solved this problem using the UserData property in a > sizer, i have added all the buttons to a sizer for display purposes and > so SizerItem objects have been created, i can then set the original > object to the UserData object by putting the following line of code in > the loop > > sizeritem = > self.topsizer.Add(channelbutton,0,wx.ALIGN_RIGHT, userData=chan) > > This way i can retrieve the item in the _channelChanged method with the > following - > > def _channelChanged(self, event): > eventobj = event.GetEventObject() > chan = self.topsizer.GetItem(eventobj).GetUserData() > > > This works fine but by looking at the API it would appear the UserData > property is not really designed for this use ("userData - Allows an > extra object to be attached to the sizer item, for use in derived > classes when sizing information is more complex than the proportion and > flag will allow for"). > > Another option would be to derive my own Button class and include the > object in there. > > Any advice on the best way to solve this problem would be appreciated. >
Exactly how I would do it depends on the rest of the application. I would probably derive my own button - never be afraid to subclass. You could also generate the buttons IDs up front, and maintain a mapping between the IDs and the channels, like so: self.mapper = {} for channel in self.channels: id = wx.NewId() self.mapper[id] = channel channelbutton = wx.Button(self, id=id, label=channel.getName()) def channelChanged(self, event): channel = self.mapper[event.Id] You could also use closures (lambdas or via a factory function) to bind the channel at the time you create the button: for channel in self.channels: channelbutton = wx.Button(self, label=channel.getName()) self.Bind(wx.EVT_BUTTON, lambda event: self.channelChanged(channel), source=channelbutton) def channelChanged(self, channel): print "Channel changed to ", channel.getName() -- http://mail.python.org/mailman/listinfo/python-list