views:

90

answers:

4

I have the following python code and I was wondering if it's possible to create those buttons in a for loop instead? I was thinking of modifying the local namespace but I'm not sure if that's a good idea. I really want the buttons to be named so that it's named consecutively.

self.todo1 = wx.TextCtrl(self, -1, "")
self.timer_label1 = wx.StaticText(self, -1, "00:00")
self.set_timer1 = wx.Button(self, -1, "Set Timer")
self.todo2 = wx.TextCtrl(self, -1, "")
self.timer_label2 = wx.StaticText(self, -1, "00:00")
self.set_timer2 = wx.Button(self, -1, "Set Timer")
self.todo3 = wx.TextCtrl(self, -1, "")
self.timer_label3 = wx.StaticText(self, -1, "00:00")
self.set_timer3 = wx.Button(self, -1, "Set Timer")
self.todo4 = wx.TextCtrl(self, -1, "")
self.timer_label4 = wx.StaticText(self, -1, "00:00")
self.set_timer4 = wx.Button(self, -1, "Set Timer")
self.todo5 = wx.TextCtrl(self, -1, "")
self.timer_label5 = wx.StaticText(self, -1, "00:00")
self.set_timer5 = wx.Button(self, -1, "Set Timer")
+3  A: 

I think the built-in setattr method is probably your best friend here. Something like this should work:

for i in range(1,6):
   setattr(self,'todo%d' % i,wx.TextCtrl(self, -1, ""))
   setattr(self,'timer_label%d' % i, wx.StaticText(self,-1,"00:00"))
   setattr(self,'set_timer%d' % i, wx.Button(self,-1,"Set Timer"))

Just remember that doing:

object.x = y

Is the same as doing:

setattr(object,'x',y)

Hope that helps!

Brent Nash
+2  A: 

use a dict:

self.set_timer = {} 
self.timer_label = {}
self.text_timer = {}

for i in range(1,5):
    self.text_timer[i] = wx.TextCtrl(self, -1, "")
    self.timer_label[i] = wx.StaticText(self, -1, "00:00")
    self.set_timer[i] = wx.Button(self, -1, "Set Timer")
olarva
If the "i" is going to be the index into the dictionary, using Lists instead of Dictionaries might even be easier. I think your method is probably the better way since it keeps the number of variables being attached to "self" constant.
Brent Nash
This won't work as expected since your first line has multiple variables all looking at the same dictionary.
tom10
i prefer dict, because I may use has_key() to search for itens...
olarva
I much prefer this to the setattr solution in another answer -- dicts are so much easier to manage than dynamically named attributes.
Bryan Oakley
thanks tom10...
olarva
olarva: prefer "in" to has_key(); "if 'x' in someDict" instead of "if someDict.has_key('x')"
Steven Sproat
A: 

I recommend against doing this. Instead, an easy and expandable approach is to make a class for each timer object. Looking at the implied functionality in your question, you're going to want to display the time correctly, reset it, take input from the text ctrl, etc, and you're code will be easier to maintain if you encapsulate all of this in a class rather than through many named variables that are distinguished by the integers in their names. Here's an example.

class TimerCtrl(object):
    def __init__(self, parent, label_number):
        self.todo = wx.TextCtrl(parent, -1, "")
        self.timer_label = wx.StaticText(parent, -1, "00:00")
        self.button = wx.Button(parent, -1, "Set Timer %i" % label_number)
        self.label_number = label_number

# and then in your other class, which I assume is some type of wx.Window
self.timer_controls = []
for i in range(5):
    self.timer_controls.append( TimerCtrl(self, i+1) )

Note that I'm not making any attempt at clever indexing of the TimerCtrl instances but instead I'm just collecting them all -- clever indexing breaks easier and usually isn't worth the hassle. Instead find a way to let the objects do the work for you. Also, you may want to have TimerCtrl inherit from a wx.Panel, or some such thing.

tom10
A: 
Mike Driscoll