I've been learning how to create Gui in python with Tkinter for almost a week. When creating free space around or creating a box and determining the dimensions of the widget using the container, Frame
you cannot modify the attributes such as padding
, borderwidht
or widht
.
This is my code:
from tkinter import *
from tkinter import ttk
root=Tk()
mainframe=ttk.Frame(root, ).grid()
mainframe['padding']=(5,10)#esta linea es la que me genera problemas y es de igual forma si quiero usar borderwidht o widht
etiqueta=ttk.Label(root,text="try").grid(row=0, column=2)
buton=ttk.Button(mainframe,text="push here",command=root.quit).grid(row=1, column=24)
root.mainloop()
and the result is:
Traceback (most recent call last):
File "/home/wonder/PycharmProjects/untitled/essays tkinter.py", line 8, in <module>
mainframe['padding']=(5,10)
TypeError: 'NoneType' object does not support item assignment
What am I doing wrong?
It is a very common error in Tkinter. The problem is the use of
grid
,place
orpack
on the same line where the widget is instantiated. It's very good to save lines but sometimes it has its consequences ツ.If this is done:
mainframe
is not an objectttk.Frame
, it is the return of the methodgrid
, which does not return anything (None
). That's why the error says:If you want to use the name of the object to change its attributes later, you need to separate the instance from the method call
grid
:You can see the difference by doing something as simple as printing the mainframe variable in both cases:
In the output we see the difference:
Exactly the same problem occurs when trying to chain the widget's method calls:
In this case the error and the problem are identical,
Entry()
create an object of the classEntry
, then.grid()
call the methodgrid
of the object, so far so good. Then it.config()
tries to call theconfig
grid output(None
) method and here we have the same problem as before. For the above to work, each method should return a reference to the object to which it belongs, that is, it cangrid
return a reference to the object created withEntry()
and notNone
. The solution is the same:If we never need to refer to the widget again, it is correct to apply the method on the same line, but in this case a variable should not be associated with the output, since we will have a lot of variables, all associated with
None
and totally useless. instead of doing:we just have to do:
On the other hand, it is not an error per se, but a very bad practice that for some reason is very widespread in Tkinter tutorials, you should never import a module in Python in the way (except justified cases, mainly to merge two spaces of Names):
Your code is simple and will not give you problems at first but it can cause a lot of headaches when using complex modules or in medium-sized projects. This form of import exposes all module identifiers in your current namespace. In principle you don't know the name of all the classes, objects or functions that the module contains, so you can end up overwriting your own functions in your Tkinter functions namespace or vice versa without realizing it. On the other hand, it makes it difficult for third parties to read the code ("Explicit better than implicit").
The proper way is to use one of these:
Your code could look like this:
Result:
Edition:
The parameters
weidht
andheight
are specified the same as the rest, with the exception that if we want to avoid the automatic adjustment carried out by the layout and that the widget is forced to take those measures, we need to use the method together:grid_propagate()