Object has no attribute error

def c():
    print('hi')

class GUIButton(object):
    def __init__(self, master):
        self.master = master
        self.mainFrame = Frame(master)

    def widgets(self, imageName, rowNumber, colNumber, command):
        buttonImage = PhotoImage(file = imageName)
        newButton = Button(self.mainFrame, image=buttonImage, width = '200', height = '153')
        newButton.grid(row = rowNumber, column = colNumber)

GUIButton.widgets(root, 'HOME.gif', 1, 1, c())

error:
File "C:/Users/Marius/Desktop/comp scio/interface2.py", line 29, in <module>
    GUIButton.widgets(root, 'HOME.gif', 1, 1, c())
  File "C:/Users/Marius/Desktop/comp scio/interface2.py", line 26, in widgets
    newButton = Button(self.mainFrame, image=buttonImage, width = '200', height = '153')
  File "C:\Users\Marius\AppData\Local\Programs\Python\Python36-32\lib\tkinter\__init__.py", line 2095, in __getattr__
    return getattr(self.tk, attr)
AttributeError: '_tkinter.tkapp' object has no attribute 'mainFrame'

I have defined the mainFrame attribute in the constructor, yet I cannot use it in other methods. If I define it in other methods, it can be used in all other methods as well, but I want it defined in the constructor.

1 Like

you call widgets before __init__

1 Like

I get the exact same error even when I call initialise before the widgets method.
I honestly have no idea why this would not work.

1 Like

Since __init__ sets that attribute and your widgets method uses it, you definitely have to call __init__ first, that’s a pretty major bug.

So if you’ve fixed that bug, and there’s still a problem, then don’t un-fix it and demand a different explanation! Start looking at the next slightly better version instead.

Or maybe you didn’t fix it at all, and that this is why the same issue remains.

Also, root isn’t defined anywhere, or at least you aren’t showing how you define it or why you expect it to have a mainFrame attribute (which your error suggests it doesn’t), same with Button, Frame, PhotoImage, and maybe a few more - what you’re showing doesn’t reproduce what you say happens and that’s kind of a problem when trying to solve it. Can’t solve what doesn’t happen.

You’re not really treating your method like a method at all, maybe it should be a completely regular function instead since that’s how you treat it. Or, if it is supposed to be a method, perhaps that says something about how it should be used instead.

You do try to access mainFrame on whatever value root refers to, so whether you expect it to have that attribute is a pretty important question. If you do expect it to be there, then root probably isn’t at all the value you expected, you mixed things up. Or failed to create it correctly in which case its initialization is wrong. Or if you don’t expect root to have such an attribute then you probably shouldn’t try to access it either - in which case you’re either doing the wrong thing with root or doing the thing wrong.

That suggests that you already know everything that should happen. In turn, it suggests that you know enough to check whether those things are happening, making it debuggable.

Or it means you haven’t got enough awareness around what should happen, in which case, get more of that. (Otherwise you’ve got some scenario where you’re writing code that you don’t know what it does … who then is telling the computer what to do? Doesn’t make sense.)

1 Like