How to configure Frame widget in Tkinter?

1

I've been learning to create Gui in Python with Tkinter for almost a week. When creating free space around or creating a box and determining the measures of the widget by using the Frame container, you can not 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?

    
asked by wonderly gonzalez 15.04.2017 в 05:19
source

1 answer

2

It is a very common error in Tkinter. The problem is the use of grid , place or pack on the same line where the widget is instantiated. It is very well that of saving lines but sometimes has its consequences ツ.

If this is done:

mainframe = ttk.Frame(root, ).grid()

mainframe is not a ttk.Frame object, it is the return of the grid method, which returns nothing ( None ). That's why the error says:

  

TypeError: 'NoneType' object does not support item assignment

If you want to use the name of the object to change its attributes later, it is necessary to separate the instance of the call from the grid method:

mainframe = ttk.Frame(root)
mainframe.grid()

You can see the difference by doing something as simple as printing the mainframe variable in both cases:

import tkinter as tk
from tkinter import ttk

root=tk.Tk()

mainframe0 = ttk.Frame(root).grid()
print(type(mainframe0))

mainframe1 = ttk.Frame(root)
mainframe1.grid()
print(type(mainframe1))

At the start we see the difference:

>>> <class 'NoneType'>
>>> <class 'tkinter.ttk.Frame'>

On the other hand, it is not a proper error but if a very bad practice that for some reason is very extended in tutorials of Tkinter, you should never import a module in Python of the form (except justified cases, mainly to merge two namespaces):

from tkinter import *

Your code is simple and will not give you problems in principle but it can cause many headaches using complex modules or in medium large projects. This form of import exposes all the identifiers of the module in your current namespace. In principle you do not know the name of all classes, objects or functions contained in the module so you can end up overwriting with your own functions in your namespace Tkinter functions or vice versa without realizing it. On the other hand, it hinders the legibility of the code by third parties ("Explicit better than implicit").

The proper way is to use one of these:

from tkinter import Tk, Button, Frame...
import tkinter
import tkinter as tk

Your code could look like this:

import tkinter as tk
from tkinter import ttk

root=tk.Tk()

mainframe = ttk.Frame(root)
mainframe.grid()
mainframe['padding'] = 5, 10

etiqueta = ttk.Label(root, text="try")
etiqueta.grid(row=0, column=2)

buton=ttk.Button(mainframe, text="push here", command=root.quit)
buton.grid(row=1, column=24)

root.mainloop()

Result:

Edit:

Parameters weidht and height are specified the same as the rest, except 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 jointly The method: grid_propagate()

import tkinter as tk
from tkinter import ttk

root=tk.Tk()

mainframe = ttk.Frame(root)
mainframe.grid()
mainframe['padding'] = 5, 10
mainframe['width'] = 100
mainframe['height'] = 100
mainframe.grid_propagate(0)

etiqueta = ttk.Label(root, text="try")
etiqueta.grid(row=0, column=2)

buton=ttk.Button(mainframe, text="push here", command=root.quit)
buton.grid(row=1, column=24)

root.mainloop()
    
answered by 15.04.2017 / 11:09
source