Rex Reign
Rex Reign

Reputation: 155

Create multiple buttons with consecutive integers in name

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")

Upvotes: 1

Views: 560

Answers (4)

Mike Driscoll
Mike Driscoll

Reputation: 33111

Personally, I'd do something like this:

----------------------------------------------------------------------

def btnBuilder(): """""" btnNum = 1 for btn in range(5): btn = wx.Button(panel, "Set Timer", name="set_timer%s" % btnNum) btn.Bind(wx.EVT_BUTTON, self.onButton) btnNum += 1

----------------------------------------------------------------------

def onButton(self, event): """""" btn = event.GetEventObject() btnName = btn.GetName() if btnName == "set_timer1": # do something

If you need to, you can add a button number argument and even a sizer to the first function to put the buttons into. I do this sort of thing when I have a bunch of buttons that will all do something similar.


Mike Driscoll

Blog: http://blog.pythonlibrary.org

Upvotes: 0

tom10
tom10

Reputation: 69242

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.

Upvotes: 0

Lauro Oliveira
Lauro Oliveira

Reputation: 2410

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")

Upvotes: 2

Brent Writes Code
Brent Writes Code

Reputation: 19623

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!

Upvotes: 3

Related Questions