Custom controls - using other controls

From: "Donn Ingle" <donn.ingle@gmail.com>
SUBJECT:
How to create custom controls using other controls - a composite control as
it were.

Don, I don't know if this is anything like what you had in mind, but below is a composite control I created for placing a name, address, city, state, zip group of controls on a panel. I created this because I was doing this over and over. I created it as a derived class of GridBagSizer because that's exactly how they would have been created otherwise and it exposes the methods I need and allows sizing to work as expected. It has a couple of options of whether single name (like business name) or person's name (lname, fname) and whether to include a title field.

Add it like a control into any panel:
        self.addr = AddressGroup(self) # Name & address fields

Hope this helps,
Michael

ยทยทยท

#===============================================
# A class based on a grid bag sizer to hold name & address controls
#===============================================
class AddressGroup(wx.GridBagSizer): # This will return a sizer
    def __init__(self, parent, single=False, title=False):
        wx.GridBagSizer.__init__(self, 2, 2)
        self.AddGrowableCol(1, 3)
        self.AddGrowableCol(5, 2)
        
        #TODO Allow for single address

        # Create the labels and fields and put them into the sizer(s)
        t=0
        if single:
            self.name = wx.TextCtrl(parent, -1, style=tcStyle)
            self.Add(wx.StaticText(parent, -1, "Name:"), (0,0), (1,1), wxACV)
            self.Add(self.name, (0,1), (1,5), wxREX, 10)
        else:
            self.lname = wx.TextCtrl(parent, -1, style=tcStyle)
            self.fname = wx.TextCtrl(parent, -1, style=tcStyle)
            self.Add(wx.StaticText(parent, -1, "Last:"), (0,0), (1,1), wxACV)
            ns = wx.BoxSizer(wx.HORIZONTAL)
            ns.Add(self.lname, 1, wxREX, 10)
            ns.Add(wx.StaticText(parent, -1, "First:"), 0, wxACV)
            ns.Add(self.fname, 1, wxREX, 10)
            self.Add(ns, (0,1), (1,4), wx.EXPAND)
        if title:
            self.title = wx.TextCtrl(parent, -1, style=tcStyle)
            self.Add(wx.StaticText(parent, -1, "Title:"), (1,0), (1,1), wxACV)
            self.Add(self.title, (1,1), (1,3), wxREX, 10)
            t=1
        self.addr1 = wx.TextCtrl(parent, -1, style=tcStyle)
        self.addr2 = wx.TextCtrl(parent, -1, style=tcStyle)
        self.city = wx.TextCtrl(parent, -1, style=tcStyle)
        self.state = wx.TextCtrl(parent, -1, style=tcStyle)
        self.zip = wx.TextCtrl(parent, -1, style=tcStyle)
        self.Add(wx.StaticText(parent, -1, "Addr 1:"), (t+1,0), (1,1), wxACV)
        self.Add(wx.StaticText(parent, -1, "Addr 2:"), (t+2,0), (1,1), wxACV)
        self.Add(self.addr1, (t+1,1), (1,5), wxREX, 10)
        self.Add(self.addr2, (t+2,1), (1,5), wxREX, 10)
        self.Add(wx.StaticText(parent, -1, "City:"), (t+3,0), (1,1), wxACV)
        csz = wx.BoxSizer(wx.HORIZONTAL)
        csz.Add(self.city, 1, wxREX, 10)
        csz.Add(wx.StaticText(parent, -1, "St:"), 0, wxACV)
        csz.Add(self.state, 0, wx.RIGHT, 10)
        csz.Add(wx.StaticText(parent, -1, "Zip:"), 0, wxACV)
        csz.Add(self.zip, 0, wxREX, 10)
        self.Add(csz, (t+3,1), (1,4), wxREX|wx.BOTTOM, 5)
        
        # Set these fields to more reasonable sizes
        self.SetItemMinSize(self.state, tw2)
        self.SetItemMinSize(self.zip, tw5)

        # Build a convenience list of controls
        if single:
            self.ctrls = [self.name]
        else:
            self.ctrls = [self.lname, self.fname]
        if title:
            self.ctrls += [self.title]
        else:
            self.ctrls += [None]
        self.ctrls += [self.addr1, self.addr2, self.city, self.state, self.zip]