Herding controls -- strategies?

Hi all,

When using wxPython in the past, I have always followed the strategy
of attaching the controls I create to self. I have generally erred on
the side of caution, and therefore attached many more items to self
than strictly required.

Lately, I have been experimenting with the opposite strategy:
Attaching as little as possible to self, and instead tracking controls
by ID (always using wx.NewId() to generate ID numbers, of course).
However, aside from having to type "self" less often, it is not clear
to me what the advantages and disadvantages of this strategy might be.

To clarify what I am talking about, here are some code snippets
(complete working example is attached).

Using the first strategy, I create a button and bind it to an event
handler like so:

self.button1 = wx.Button(self, wx.ID_ANY, 'Button 1')
self.Bind(wx.EVT_BUTTON, self.OnButton1, self.button1)

Using the second strategy, I work like so:

self.ID_BUTTON2 = wx.NewId()
button2 = wx.Button(self, self.ID_BUTTON2, 'Button 2')
self.Bind(wx.EVT_BUTTON, self.OnButton2, id = self.ID_BUTTON2)

The second strategy complicates the event handler a little bit,
requiring an extra line of code.

def OnButton1(self, event):
    self.button1.SetLabel('Waaah!')

def OnButton2(self, event):
    button = self.FindWindowById(self.ID_BUTTON2)
    button.SetLabel('Ouch!')

Both methods seem to work equally well, but the second requires a
little extra code and frequent calls to FindWindowById. Do I gain
anything by using it? For example, but not attaching so many controls
to self, do I reduce my memory footprint somehow? Or, since all of
those data structures have to sit in memory somewhere anyway, does it
make no difference? When I get to a complicated GUI, is FindWindowById
going to create a noticeable drag on performance as compared to simply
referring to a class property?

I initially started experimenting in this manner to solve some sort of
inter-panel communication issue whose details I now forget. It seems
that pubsub is a much more elegant solution to that problem, so maybe
this is all moot anyway, but it remains a topic that has piqued my
interest if for no other reason than to better understand wxPython.

Thanks,

Alan

demo.py (980 Bytes)

Hi Alan,

···

On 11/25/2011 01:22 PM, Alan Ristow wrote:

Hi all,

When using wxPython in the past, I have always followed the strategy
of attaching the controls I create to self. I have generally erred on
the side of caution, and therefore attached many more items to self
than strictly required.

Lately, I have been experimenting with the opposite strategy:
Attaching as little as possible to self, and instead tracking controls
by ID (always using wx.NewId() to generate ID numbers, of course).
However, aside from having to type "self" less often, it is not clear
to me what the advantages and disadvantages of this strategy might be.

To clarify what I am talking about, here are some code snippets
(complete working example is attached).

Using the first strategy, I create a button and bind it to an event
handler like so:

self.button1 = wx.Button(self, wx.ID_ANY, 'Button 1')
self.Bind(wx.EVT_BUTTON, self.OnButton1, self.button1)

Using the second strategy, I work like so:

self.ID_BUTTON2 = wx.NewId()
button2 = wx.Button(self, self.ID_BUTTON2, 'Button 2')
self.Bind(wx.EVT_BUTTON, self.OnButton2, id = self.ID_BUTTON2)

The second strategy complicates the event handler a little bit,
requiring an extra line of code.

def OnButton1(self, event):
     self.button1.SetLabel('Waaah!')

def OnButton2(self, event):
     button = self.FindWindowById(self.ID_BUTTON2)
     button.SetLabel('Ouch!')

Both methods seem to work equally well, but the second requires a
little extra code and frequent calls to FindWindowById. Do I gain
anything by using it? For example, but not attaching so many controls
to self, do I reduce my memory footprint somehow? Or, since all of
those data structures have to sit in memory somewhere anyway, does it
make no difference? When I get to a complicated GUI, is FindWindowById
going to create a noticeable drag on performance as compared to simply
referring to a class property?

I initially started experimenting in this manner to solve some sort of
inter-panel communication issue whose details I now forget. It seems
that pubsub is a much more elegant solution to that problem, so maybe
this is all moot anyway, but it remains a topic that has piqued my
interest if for no other reason than to better understand wxPython.

I find that I assign to self and use less and less ID's, mainly because everyone seems to recommend against using them, see e.g. point 3 in:

http://wiki.wxpython.org/wxPython%20Style%20Guide

Werner

Using the first strategy, I create a button and bind it to an event

handler like so:

self.button1 = wx.Button(self, wx.ID_ANY, ‘Button 1’)

self.Bind(wx.EVT_BUTTON, self.OnButton1, self.button1)

Using the second strategy, I work like so:

self.ID_BUTTON2 = wx.NewId()

button2 = wx.Button(self, self.ID_BUTTON2, ‘Button 2’)

self.Bind(wx.EVT_BUTTON, self.OnButton2, id = self.ID_BUTTON2)

The second strategy complicates the event handler a little bit,

requiring an extra line of code.

def OnButton1(self, event):

self.button1.SetLabel('Waaah!')

def OnButton2(self, event):

button = self.FindWindowById(self.ID_BUTTON2)

button.SetLabel('Ouch!')

Or you could do it this way, which is slightly simpler:

button = wx.Button(self)

button.Bind(wx.EVT_BUTTON, self.OnButton)

def OnButton(self,event):
event.GetEventObject().SetLabel('Pressed!)

I’m trying to get away from attaching everything to self, because it clutters up the namespace. I don’t think it will affect speed of the application in any noticeable way, but it makes managing one’s code easier, I think, and cuts down on typing. If I need to keep references to a particular object, I can use lists, tuples, or dicts. If I reference the object frequently, I might then make it a child of self. But I admit I’m not all that consistent about this yet.

Che

···

On Fri, Nov 25, 2011 at 7:22 AM, Alan Ristow alan.ristow@gmail.com wrote:

Both methods seem to work equally well, but the second requires a

little extra code and frequent calls to FindWindowById. Do I gain

anything by using it? For example, but not attaching so many controls

to self, do I reduce my memory footprint somehow? Or, since all of

those data structures have to sit in memory somewhere anyway, does it

make no difference? When I get to a complicated GUI, is FindWindowById

going to create a noticeable drag on performance as compared to simply

referring to a class property?

I initially started experimenting in this manner to solve some sort of

inter-panel communication issue whose details I now forget. It seems

that pubsub is a much more elegant solution to that problem, so maybe

this is all moot anyway, but it remains a topic that has piqued my

interest if for no other reason than to better understand wxPython.

Thanks,

Alan

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en

Great question. I too keep having this question nag at me. So many
angles to view this.

Historically, IDs where an easy way to refer to window objects in the
C programing days of WIndows SDK. Then there was a move to accessing
Windows objects via string names, short lived. And in high level
languages like Python IDs and widget names are not even necessary, as
you can lean towards a more Pythonic syntax and use "objects"

So there seems this ying yang between the historical underlying
framework, a syntax which doesn't really promote noticiable
performance, i.e. a 16 bit identifier use to be known as the handle or
later a 16 bit identifier from the C enum. which hasn't gone away to
the more OOP syntax of "objects".

wxPython laying on top of wxwidgets on top of original GUI APIs will
likely have this for a long time.

But you have to admit, Robin et.al have really made programing GUI
more fun with the pretty Python language.

I to end up trying to stay away from IDs. But then 1. I'm a hobbiest
so my apps are pretty simple. and 2. If you inherit a real project
you'll likely continue using thier conventions.

I find making my wxPython apps look more Pythonic then wx-ish look
better and helps with seperating Gui from non-gui.

I have this fear that one day, Robin D. will quit working on anything
wxPythonic for some unexpected reason and for some span of time the
package will go dormant and I'll need to move my current apps to
tinker or gtk or some other package.

So seperating data and processing from presentation is something
running in the back of my mind.

Then there is the opposite side of the coin: IDs are another way of
just accessing objects.

My preference is somewhere in the middle. I avoid using IDs where I can and I only make attributes of self for items that I know that I'll need to reference later. If I miss some of them then it's easy enough to do a search/replace of "foo" --> "self.foo" later.

···

On 11/25/11 4:22 AM, Alan Ristow wrote:

Hi all,

When using wxPython in the past, I have always followed the strategy
of attaching the controls I create to self. I have generally erred on
the side of caution, and therefore attached many more items to self
than strictly required.

Lately, I have been experimenting with the opposite strategy:
Attaching as little as possible to self, and instead tracking controls
by ID (always using wx.NewId() to generate ID numbers, of course).
However, aside from having to type "self" less often, it is not clear
to me what the advantages and disadvantages of this strategy might be.

--
Robin Dunn
Software Craftsman

Thanks to everybody for the replies -- they have been very helpful! I like the idea of using GetEventObject for a collection of objects that have to be processed the same way, I will avoid explicitly using IDs as much as possible, and I will attach only a minimal number of GUI elements to self to keep my namespaces clean.

Best,

Alan

···

On 11/25/2011 06:04 PM, C M wrote:

Or you could do it this way, which is slightly simpler:

button = wx.Button(self)
button.Bind(wx.EVT_BUTTON, self.OnButton)

def OnButton(self,event):
     event.GetEventObject().SetLabel('Pressed!)

I'm trying to get away from attaching everything to self, because it
clutters up the namespace.

I do what Robin does. I usually know in advance which widgets I’ll need access to later and just attach those to “self”. I hardly ever deal with IDs.

···

Mike Driscoll

Blog: http://blog.pythonlibrary.org