tkinter 'NoneType' object has no attribute 'pack' (Still works?)
Solution 1
When you get an error such as 'NoneType' object has no attribute 'X'
, that means you have a variable whose value is None
, and you are trying to do None.X()
. It doesn't matter if you're using tkinter or any other package. So, you have to ask yourself, "why does my variable have the value None
?"
The problem is this line:
but1 = tkinter.Button(window, text="Button1", command=btn1).grid(column = 1, row = 1)
In python, when you do foo=x(...).y(...)
, foo
will always have the value of the last function called. In the case above, but
will have the value returned by .grid(column = 1, row = 1)
, and grid
always returns None
. Thus, but1
is None
, and thus you get `'NoneType' object has no attribute 'pack'".
So, the immediate fix is to move your call to grid
to a separate line:
but1 = tkinter.Button(window, text="Button1", command=btn1)
but1.grid(column = 1, row = 1)
With that, the error will go away.
However, you have another problem. Calling grid
and then later calling pack
isn't going to do what you think it's going to do. You can only have one geometry manager in effect at a time for any given widget, and both grid
and pack
are geometry managers. If you do but1.grid(...)
and later but1.pack(...)
, any effect that calling grid
had will be thrown away, as if you had never called grid
in the first place.
You have to decide whether you want to use grid
, or whether you want to use pack
, and use only one or the other for all widgets in your root window.
Solution 2
Try changing this:
but1 = tkinter.Button(window, text="Button1", command=btn1).grid(column = 1, row = 1)
into this:
but1 = tkinter.Button(window, text="Button1", command=btn1)
but1.grid(column = 1, row = 1)
Chances are the .grid()
method doesn't return a value.
Related videos on Youtube
I_do_python
Updated on September 15, 2022Comments
-
I_do_python over 1 year
I'm fairly new to Python and have just started to play around with tkinter. Running the below code I get an attribute error for
but1.pack()
(NoneType
object has no attributepack
). But as far as I can tell this error is having no effect on the window's functionality, it is stillpack
ing the button. The window still appears and all the buttons behave as expected.Searching I can see other people have had this error, but none of the answers given solved my problem. Hoping you can help.
The code:
import tkinter import ctypes lst=[] user32 = ctypes.windll.user32 screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1) def closewindow(): window.destroy() def btn1(): lst.append("Button1") def btn2(): lst.append("Button2") window = tkinter.Tk() size = str(screensize[0])+'x'+str(screensize[1]) window.geometry(size) but1 = tkinter.Button(window, text="Button1", command=btn1).grid(column = 1, row = 1) but2 = tkinter.Button(window, text="Button2", command=btn2).grid(column = 2, row = 1) ext = tkinter.Button(window, text="Stop", command=closewindow).grid(column = 3, row = 1) but1.pack() but2.pack() ext.pack() window.mainloop()
The callback;
Traceback (most recent call last): File "C:\Python33\temp.py", line 59, in <module> but1.pack() AttributeError: 'NoneType' object has no attribute 'pack'
-
I_do_python over 10 yearsThanks, that appears to be the cause of the error. But now the .grid() method isn't registering. The buttons are in default locations (i.e. as if no grid() method was applied).
-
Amber over 10 years@I_do_python That's because
grid()
andpack()
are mutually exclusive. Use one or the other. -
I_do_python over 10 yearsThanks Amber. Just sticking to grid and it's all working now.