pedram
pedram

Reputation: 3087

How do I get the values of TextCtrl created during a loop in wxpython

Say I am creating 6 text control fields using a loop like so:

ticker_items = ['bid', 'ask', 'open', 'close', 'high', 'low']
for item in ticker_items:
    wx.TextCtrl(self.panel, -1, value=item, size=(-1, -1))

How can I update these after creation?

Upvotes: 1

Views: 2504

Answers (4)

Yoriz
Yoriz

Reputation: 3625

A really easy way is to store the ctrl's in a dictionary. I've modified Mike's code to use a dictionary instead see below.

import wx

########################################################################
class MyPanel(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)

        sizer = wx.BoxSizer(wx.VERTICAL)
        ticker_items = ['bid', 'ask', 'open', 'close', 'high', 'low']
        self.ticker_ctrls = {}
        for item in ticker_items:
            ctrl = wx.TextCtrl(self, value=item, size=(-1, -1), name=item)
            sizer.Add(ctrl)
            self.ticker_ctrls[item] = ctrl

        btn = wx.Button(self, label="Update")
        btn.Bind(wx.EVT_BUTTON, self.updateTextCtrls)
        sizer.Add(btn)

        self.SetSizer(sizer)

    #----------------------------------------------------------------------
    def updateTextCtrls(self, event):
        """"""
        self.ticker_ctrls['bid'].SetValue('$100')
        self.ticker_ctrls['ask'].SetValue('$500')


########################################################################
class MainFrame(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="TextCtrl Tutorial")
        panel = MyPanel(self)
        self.Show()

if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()

Upvotes: 2

Mike Driscoll
Mike Driscoll

Reputation: 33071

There's a simpler way. You can pass a unique name to the text controls and use it to update them. I've provided a simple example where I update the first couple of controls below:

import wx

########################################################################
class MyPanel(wx.Panel):
    """"""

    #----------------------------------------------------------------------
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)

        sizer = wx.BoxSizer(wx.VERTICAL)
        ticker_items = ['bid', 'ask', 'open', 'close', 'high', 'low']
        for item in ticker_items:
            sizer.Add(wx.TextCtrl(self, value=item, size=(-1, -1), name=item) )

        btn = wx.Button(self, label="Update")
        btn.Bind(wx.EVT_BUTTON, self.updateTextCtrls)
        sizer.Add(btn)

        self.SetSizer(sizer)

    #----------------------------------------------------------------------
    def updateTextCtrls(self, event):
        """"""
        txtCtrls = [widget for widget in self.GetChildren() if isinstance(widget, wx.TextCtrl)]
        for ctrl in txtCtrls:
            if ctrl.GetName() == "bid":
                ctrl.SetValue("$100")
            elif ctrl.GetName() == "ask":
                ctrl.SetValue("$500")


########################################################################
class MainFrame(wx.Frame):
    """"""

    #----------------------------------------------------------------------
    def __init__(self):
        """Constructor"""
        wx.Frame.__init__(self, None, title="TextCtrl Tutorial")
        panel = MyPanel(self)
        self.Show()

if __name__ == "__main__":
    app = wx.App(False)
    frame = MainFrame()
    app.MainLoop()

The only way to create references to the text controls is to use the setattr method that ikaros45 mentioned.

Upvotes: 2

joaquin
joaquin

Reputation: 85603

You can not. You either must save the object in some way (p.e. a list of objects) or give a different ID to each TextCtrl.

For example:

ticker_items = [('bid', 1000), ('ask', 1001),
                ('open', 1002), ('close', 1003),
                ('high', 1004), ('low', 1005)]

for item, id in ticker_items:
    wx.TextCtrl(self.panel, id=id, value=item, size=(-1, -1))

Then you can use

my_textctrl = self.panel.FindWindowById(id_of_my_ctrl)

to get a specific control back

Alternatively, using a list:

ticker_items = ['bid', 'ask', 'open', 'close', 'high', 'low']
self.my_controls = []
for item in ticker_items:
    text_control = wx.TextCtrl(self.panel, -1, value=item, size=(-1, -1))
    self.my_controls.append(text_control)

The you retrieve your text number 0 with

 my_textctrl = self.my_controls[0]

Upvotes: 2

bgusach
bgusach

Reputation: 15153

You cannot create TextCtrl's like this if you want to later refer to them. Store them.

One way is to add them to the object by using settatr(), and optionally a prefix to give extra information (I used '_text')

http://docs.python.org/2/library/functions.html#setattr

ticker_items = ['bid', 'ask', 'open', 'close', 'high', 'low']
for item in ticker_items:
    text_control = wx.TextCtrl(self.panel, -1, value=item, size=(-1, -1))
    setattr(self, '_text_' + item, text_control)

And later you can access it and change the value by using for example:

self._text_bid.SetValue('Bid v2.0')

Upvotes: 1

Related Questions