1

What am I doing wrong? I want the 'refreshB' button to call the 'update' def but I get a nameError instead

class monitor():
    def update(self):
        print "Called"

    mon = Tk()
    mainFrame = Frame(mon)
    mainFrame.grid(row=1, column=1)

    optionFrame = Frame(mainFrame)
    optionFrame.grid(row=1, column=1)

    refreshB = ttk.Button(optionFrame, text='Refresh', command=lambda: update('self') )
    refreshB.grid(row=1, column=1)

    mon.mainloop()

monitor()


**NameError: global name 'update' is not defined**

I an not very familiar with Classes, is there something else I am supposed to add?

If the script above was not a class then I would use:

refreshB = ttk.Button(optionFrame, text='Refresh', command=lambda: update )

Which would works fine...

1
  • You're treating the class construct as a function. They're not the same thing. When you call a class, it doesn't execute the code inside the class. Instead, it calls the __init__ method defined in the class and returns a new instance of the class. Commented Apr 30, 2012 at 21:15

2 Answers 2

1

Place all your initialization code inside an initialization function. Then refer to update() as self.update().

    class Monitor(object):
        def update(self, event):
            print "Called"

        def __init__(self):
            self.mon = Tk()
            self.mainFrame = Frame(self.mon)
            self.mainFrame.grid(row=1, column=1)

            self.optionFrame = Frame(self.mainFrame)
            self.optionFrame.grid(row=1, column=1)

            self.refreshB = ttk.Button(self.optionFrame, text='Refresh', command=self.update)
            self.refreshB.grid(row=1, column=1)

        def run(self):
            self.mon.mainloop()

    monitor = Monitor()
    monitor.run()

the update() reference doesn't work here because it's an instancemethod and not a classmethod. Not because of the use of lambda--although I have no idea why you'd need to use a lambda function anyways. My solution involves you creating an instance of Monitor. This is useful because it allows you to control when the code within Monitor is executed. (Otherwise the code in your class body is executed at definition time. All calling monitor() does is return an instance of the class monitor--it doesn't execute the body of the code)

Sign up to request clarification or add additional context in comments.

1 Comment

Ah thank you for clearing that up for me. I'm still really new to Python, only been using it for around 3 months now. I used the lambda so that I could pass objects through to the called def. Its worked for me in the past but I am just learning how to use Classes. Thanks again for your help and time :)
0

You shouldn't really have code that has side effects directly in a class. You almost certainly want all that code to be in the __init__ function instead, which gets called after your monitor object is created:

def __init__(self):
    mon = Tk()
    etc...

Next, update is an instance method so it has to be called on an object. You probably want this:

refreshB = ttk.Button(optionFrame, text='Refresh', command=lambda: self.update('self') )

But then, since your update method doesn't take any arguments beyond the implicit self argument, you actually probably want this:

refreshB = ttk.Button(optionFrame, text='Refresh', command=lambda: self.update() )

Finally, the lambda is useless indirection. Why don't you just give the method directly as a callback instead of wrapping it in a lambda?

refreshB = ttk.Button(optionFrame, text='Refresh', command=self.update )

1 Comment

Ah yes you are correct as well. I am using the lambda to pass arguments, I just forgot to include it in my example code. But thank you very much, your explanation is very helpful as well. If I could give you a check mark as well I would do so.

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.