I'd like to propose a change to the current API for sizers. Since the
current API isn't documented in the wxWindows reference, this change
shouldn't be too dramatic. I'll outline the existing API followed by
my proposed change.
Existing Sizer API
···
==================
Once you create a sizer, you can modify the list of items in a sizer
using add, insert, prepend and remove operations (and the somewhat
related show, hide, and isShown operations). The items in a sizer can
be any combination of windows, spacers, and other sizers. The C++
signatures differ for each of the operations depending on the type of
item involved. Since Python doesn't support overloaded method names,
wxPython provides two ways of dealing with the C++ API: it provides
separate methods for each type, and it detects the type of the first
parameter within the generic call and then calls the appropriate
specific method. Let's look at a concrete example.
The wxWindow API provides for an Add method, with three different
signatures. wxPython provides the following variations::
def AddSizer(self, sizer, option=0, flag=0, border=0, userData=wx.NULL):
def AddSpacer(self, width, height, option=0, flag=0, border=0, userData=wx.NULL):
def AddWindow(self, window, option=0, flag=0, border=0, userData=wx.NULL):
The code for Add does some type inspection and calls the specific
method::
def Add(self, *args, **kw):
if type(args[0]) == type(1):
apply(self.AddSpacer, args, kw)
elif isinstance(args[0], wxSizerPtr):
apply(self.AddSizer, args, kw)
elif isinstance(args[0], wxWindowPtr):
apply(self.AddWindow, args, kw)
else:
raise TypeError, 'Expected int, wxSizer or wxWindow parameter'
Proposed Sizer API
I find the current solution inelegant and verbose. So I'd like to
propose the following change. If you look at the preceding example
you'll see the the various Add* signatures are very similar. The only
real problem is the spacer variation which requires two initial
parameters -- width and height. But if we express these as a tuple,
then all the signatures will have the same number of elements.
So what I would like to see is the elimination of the Add* variations,
leaving a single Add method that looks like this::
def Add(self, item, option=0, flag=0, border=0, userData=wx.NULL):
"""Add item to sizer. Item is either a window, sizer, or
(width, height) tuple representing the size of a spacer."""
The code for this Add method would check the type of the first item
and respond accordingly. In order to maintain backward compatibility,
the actual code will still have to allow the old spacer signature to
work, but I don't think we should document it or encourage its use.
New code examples should use a (width, height) tuple instead.
Similar changes should be made to the Insert*, Prepend*, Remove*,
Hide*, IsShown*, SetItemMinSize*, and Show* methods. Each of these
has two or three variations, in addition to the base method, resulting
in an overly large API. I think the variations should be dropped and
the base signature should be modified, if necessary, to allow multiple
object types for some of its parameters.
Issues
None of the wxPython variants are documented in the wxWindows manual,
so no changes are needed there.
As you've no doubt heard me say before, I believe sooner is better
than later and would like to make this change now.
This change only effects code that uses the wxPython variants, and I
wasn't able to find any examples that did. For instance, the examples
on the wiki use Add(...), not AddWindow(...) or AddSizer(...).
Boa doesn't use sizers, so this change won't effect Boa.
I don't know what the other designers do with sizers. Anyone?
Opinions
What do the rest of you think about this proposal?
What issues have I missed?
--
Patrick K. O'Brien
Orbtech http://www.orbtech.com/web/pobrien
-----------------------------------------------
"Your source for Python programming expertise."
-----------------------------------------------