Search code examples
pythonwxpython

Create objects obj0 through objN in Python, for arbitrary N?


I'm working on a GUI and I'd like to create a variable number of buttons, depending on what is input by user. How should I go about this?

More precisely, the user opens a data file with a number of datasets, N. I would like to create N buttons with the ith button having the name of the ith dataset.

Something like... (conceptually, obviously this won't work)

import wx

# create sizer
hbox1=wx.GridBagSizer(4,4)

# create file button and add to sizer
fbtn = wx.Button(dv, label=file)
hbox1.Add(fbtn, pos=(jf,0))

# read file to get dataset names
dsetnames=[<dataset names for file>]

# create bottons for datasets found in file
jd=0 # datasets
for ds in dsetnames:
  self.dbtn<jd> = wx.Button(dv, label=ds)
  hbox1.Add(self.dbtn<jd>, pos=(jd,1))
  jd+=1

Thank you.

I found a solution but I don't have the privilege yet to answer questions, so I'll add it here. Generally, the solution here is to create a dictionary with the object names as the keys and the objects as the values.

import wx

dv=wx.Panel(self)
# create sizer
hbox1=wx.GridBagSizer(4,4)

# create file button and add to sizer
# filename file input by user
fbtn = wx.Button(dv, label=file)
hbox1.Add(fbtn, pos=(jf,0))

# read file to get dataset names
dsetnames=[<dataset names for file>]

# create empty dictionary for objects
self.dbtn=dict()    

# create bottons for datasets found in file
jd=0 # datasets
for ds in dsetnames:
  objname=ds
  self.dbtn.update({objname:wx.Button(dv, label=ds)}) # update dictionary with individual objects
  hbox1.Add(self.dbtn[objname], pos=(jd,1))
  jd+=1

I believe the following may be related.

Create Hash for Arbitrary Objects?


Solution

  • I prefer using a list so that the items read from the file are in the correct order. Dictionaries do not have a standard order, although you could use an OrderedDict from the collections library. Anyway, here's an approach that uses a list:

    import wx
    
    ########################################################################
    class MyPanel(wx.Panel):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self, parent):
            """Constructor"""
            wx.Panel.__init__(self, parent)
    
            btn_list = self.getButtons()
    
            btn_sizer = wx.BoxSizer(wx.VERTICAL)
    
            for index, btn in enumerate(btn_list):
                name = "button%i" % index
                b = wx.Button(self, label=btn, name=name)
                b.Bind(wx.EVT_BUTTON, self.onButton)
                btn_sizer.Add(b, 0, wx.ALL|wx.CENTER, 5)
    
            self.SetSizer(btn_sizer)
    
        #----------------------------------------------------------------------
        def getButtons(self):
            """
            Here you would put code to get a list of button labels from a file
            """
            return ["alpha", "bravo", "charlie"]
    
        #----------------------------------------------------------------------
        def onButton(self, event):
            """"""
            btn = event.GetEventObject()
            print "The button's label is '%s'" % btn.GetLabel()
            print "The button's name is '%s'" % btn.GetName()
    
    
    ########################################################################
    class MyFrame(wx.Frame):
        """"""
    
        #----------------------------------------------------------------------
        def __init__(self):
            """Constructor"""
            wx.Frame.__init__(self, None, title="Buttons")
            panel = MyPanel(self)
            self.Show()
    
    if __name__ == "__main__":
        app = wx.App(False)
        frame = MyFrame()
        app.MainLoop()
    

    You might find the following articles helpful as well: