Chris Mellon wrote: > 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()
Two good ideas, i used the mapping system, works and seems like a slightly more elegant way of doing things. Many thanks! Ian -- http://mail.python.org/mailman/listinfo/python-list