471,853 Members | 1,672 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,853 software developers and data experts.

Catching wx events

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._channelChan ged)

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.

Many thanks

Ian

Jan 18 '07 #1
2 1239
On 18 Jan 2007 06:12:17 -0800, Cruelemort <ia********@gmail.comwrote:
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._channelChan ged)

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()
Jan 18 '07 #2

Chris Mellon wrote:
On 18 Jan 2007 06:12:17 -0800, Cruelemort <ia********@gmail.comwrote:
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._channelChan ged)

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

Jan 18 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Olli Piepponen | last post: by
reply views Thread by Ayende Rahien | last post: by
reply views Thread by spammy | last post: by
9 posts views Thread by vijay21 | last post: by
reply views Thread by Jeffrey | last post: by
3 posts views Thread by Billy Porter | last post: by
3 posts views Thread by Robert Inder | last post: by
5 posts views Thread by lord.zoltar | last post: by
NeoPa
reply views Thread by NeoPa | last post: by
aboka
reply views Thread by aboka | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.