0

I'm learning wx and I've got a problem like this: let's say I create few StaticText objects and then I want to change its labels on some events. example:

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent=parent)
        self.panel=wx.Panel(self)
        for i in range(5):
            self.button=wx.Button(self.panel, -1, label='b'+str(i), pos=(20,30*i))
            self.button.Bind(wx.EVT_BUTTON, self.on_button)
            self.label=wx.StaticText(self.panel, -1, label='label'+str(i), pos=(120,30*i), name='label'+str(i))

    def on_button(self, event):
        b=event.GetEventObject().GetLabel()
        if b.endswith('1'):
            self.label1.SetLabel('sss')

x=wx.App()
y=MyFrame(None).Show()
x.MainLoop()

so, as you can see I want to change label of self.label1 I've created earlier, and I can't do that because of an error: in on_button; AttributeError: 'MyFrame' object has no attribute 'label1'

I think I have to change something while creating objects but I don't know what.

2 Answers 2

1

Well the first issue is that on each iteration through the for loop, you overwrite the self.button and the self.label instances. You never create a variable called "self.label1". There are a couple of approaches to fix this. Here's one simple way to do it:

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent=parent)
        self.panel=wx.Panel(self)
        for i in range(5):
            self.button=wx.Button(self.panel, -1, label='b'+str(i), pos=(20,30*i))
            self.button.Bind(wx.EVT_BUTTON, self.on_button)
            self.label=wx.StaticText(self.panel, -1, label='label'+str(i), pos=(120,30*i), name='label'+str(i))

    def on_button(self, event):
        b=event.GetEventObject().GetLabel()

        if b.endswith('1'):
            newLabel = "sss"
            self.resetLabel('1', newLabel)
        elif b.endswith('2'):
            self.resetLabel('2', "Number 2!")

    #----------------------------------------------------------------------
    def resetLabel(self, number, newLabel):
        """"""
        lbls = [widget for widget in self.panel.GetChildren() if isinstance(widget, wx.StaticText)]
        for lbl in lbls:
            if number in lbl.GetLabel():
                lbl.SetLabel(newLabel)
                break

x=wx.App()
y=MyFrame(None).Show()
x.MainLoop()

You could also use setattr and getattr to create the self.label(1-N) dynamically like this:

import wx

class MyFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent=parent)
        self.panel=wx.Panel(self)
        for i in range(5):
            setattr(self, "button%s" % i, 
                    wx.Button(self.panel, -1, label='b'+str(i), pos=(20,30*i))
                    )
            btn = getattr(self, "button%s" % i)
            btn.Bind(wx.EVT_BUTTON, self.on_button)
            setattr(self, "label%s" % i,
                    wx.StaticText(self.panel, -1, label='label'+str(i), pos=(120,30*i), name='label'+str(i))
                    )
        print

    def on_button(self, event):
        b=event.GetEventObject().GetLabel()

        if b.endswith('1'):
            self.label1.SetLabel("sss")
        elif b.endswith('2'):
            self.label2.SetLabel("Number 2!")



x=wx.App()
y=MyFrame(None).Show()
x.MainLoop()
Sign up to request clarification or add additional context in comments.

Comments

0

You could use a dict to map buttons to labels:

self.label[button] = label

Then, given an event associated with a button, you can find the associated label:

    button = event.GetEventObject()
    label = self.label[button]

import wx


class MyFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent=parent)
        self.panel = wx.Panel(self)
        self.label = {}
        for i in range(5):
            button = wx.Button(
                self.panel, -1, label='b' + str(i), pos=(20, 30 * i))
            button.Bind(wx.EVT_BUTTON, self.on_button)
            label = wx.StaticText(self.panel, -1, label='label' + str(
                i), pos=(120, 30 * i), name='label' + str(i))
            self.label[button] = label

    def on_button(self, event):
        button = event.GetEventObject()
        label = self.label[button]
        label.SetLabel('sss')

x = wx.App()
y = MyFrame(None).Show()
x.MainLoop()

1 Comment

that's also great solution. I haven't even thought about using dictionaries

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.