Later we will discuss the widgets, the building blocks of your GUI application. How do widgets get arranged in a window?
Although there are three different “geometry
managers” in Tkinter, the author strongly prefers
the .grid() geometry manager for pretty much
everything. This manager treats every window or frame as a
table—a gridwork of rows and columns.
A cell is the area at the intersection of one row and one column.
The width of each column is the width of the widest cell in that column.
The height of each row is the height of the largest cell in that row.
For widgets that do not fill the entire cell, you can specify what happens to the extra space. You can either leave the extra space outside the widget, or stretch the widget to fit it, in either the horizontal or vertical dimension.
You can combine multiple cells into one larger area, a process called spanning.
When you create a widget, it does not appear until you register it with a geometry manager. Hence, construction and placing of a widget is a two-step process that goes something like this:
self.thing=Constructor(parent, ...) self.thing.grid(...)
where
is one of the widget classes like ConstructorButton,
Frame, and so on, and parent is
the parent widget in which this child widget is being
constructed. All widgets have a .grid()
method that you can use to tell the geometry manager where
to put it.
To display a widget
on your
application screen:
w
w.grid(option=value, ...)
This method registers a widget
with the grid
geometry manager—if you don't do this, the widget
will exist internally, but it will not be visible on the
screen.
w
Here are the options to the .grid() geometry
management method:
column | The column number where you want the widget gridded, counting from zero. The default value is zero. |
columnspan |
Normally a widget occupies only one cell in the
grid. However, you can grab multiple cells of a
row and merge them into one larger cell by
setting the columnspan option to
the number of cells. For example,
would place widget in a cell that spans
columns 2, 3, and 4 of row 0.
|
in_ |
To register as a child of some widget , use in_=. The new parent must be a descendant of
the widget used when was created.
|
ipadx | Internal x padding. This dimension is added inside the widget inside its left and right sides. |
ipady | Internal y padding. This dimension is added inside the widget inside its top and bottom borders. |
padx | External x padding. This dimension is added to the left and right outside the widget. |
pady | External y padding. This dimension is added above and below the widget. |
row | The row number into which you want to insert the widget, counting from 0. The default is the next higher-numbered unoccupied row. |
rowspan |
Normally a widget occupies only one cell in the
grid. You can grab multiple adjacent cells of a
column, however, by setting the rowspan option to the number of cells to
grab. This option can be used in combination
with the columnspan option to grab
a block of cells. For example, would place widget in
an area formed by merging 20 cells, with row
numbers 3–6 and column numbers 2–6.
|
sticky | This option determines how to distribute any extra space within the cell that is not taken up by the widget at its natural size. See below. |
If you do not provide a sticky
attribute, the default behavior is to center the
widget in the cell.
You can position the widget in a corner of the
cell by using sticky=NE (top
right), SE (bottom right),
SW (bottom left), or
NW (top
left).
You can position the widget centered against one side
of the cell by using sticky=N (top
center), E (right center),
S (bottom center), or W
(left center).
Use sticky=N+S to stretch
the widget vertically but leave it centered
horizontally.
Use sticky=E+W to stretch it
horizontally but leave it centered
vertically.
Use sticky=N+E+S+W to stretch the widget
both horizontally and vertically to fill the
cell.
The other combinations will also work. For
example, sticky=N+S+W will
stretch the widget vertically and place it against
the west (left) wall.
These grid-related methods are defined on all widgets:
w.grid_bbox ( column=None, row=None,
col2=None, row2=None )
Returns a 4-tuple describing the bounding box of
some or all of the grid system in widget .
The first two numbers returned are the wx and y coordinates of the upper left corner of the area,
and the second two numbers are the width and
height.
If you pass in column and row arguments, the returned bounding box
describes the area of the cell at that column and
row. If you also pass in col2 and
row2 arguments, the returned
bounding box describes the area of the grid from
columns column to col2 inclusive, and from rows row to
row2 inclusive.
For example, returns the bounding box of four cells,
not one.
w.grid_bbox(0, 0, 1,
1)
w.grid_forget()
This method makes widget
disappear from the screen. It still exists, it
just isn't visible. You can use w.grid() it to make it appear again, but it
won't remember its grid options.
w.grid_info()
Returns a dictionary whose keys are w's option
names, with the corresponding values of those
options.
w.grid_location (
x, y )
Given a coordinates ( relative to the containing widget, this
method returns a tuple x, y)( describing what cell of col, row)'s grid
system contains that screen coordinate.
w
w.grid_propagate()
Normally, all widgets
propagate their dimensions,
meaning that they adjust to fit the contents.
However, sometimes you want to force a widget to be
a certain size, regardless of the size of its
contents. To do this, call
where
w.grid_propagate(0)
is the widget whose size you want to
force.
w
w.grid_remove()
This method is like
.grid_forget(), but its grid
options are remembered, so if you
.grid() it again, it will
use the same grid configuration options.
w.grid_size()
Returns a 2-tuple containing the number of columns
and the number of rows, respectively, in 's
grid system.
w
w.grid_slaves ( row=None, column=None
)
Returns a list of the widgets managed by widget
. If no arguments are provided, you will get
a list of all the managed widgets. Use the wrow= argument to select only the widgets
in one row, or the column= argument
to select only the widgets in one column.
Unless you take certain measures, the width of a grid
column inside a given widget will be equal to the width
of its widest cell, and the height of a grid row will
be the height of its tallest cell. The
sticky attribute on a widget
controls only where it will be placed if it doesn't
completely fill the cell.
If you want to override this automatic sizing of columns
and rows, use these methods on the
parent widget that contains
the grid layout:
w
w.columnconfigure ( N, option=value, ... )
In the grid layout inside widget , configure
column w so that the given N has the given optionvalue. For options, see the table below.
w.rowconfigure ( N, option=value, ... )
In the grid layout inside widget , configure
row w
so that the given N has the given optionvalue. For options, see the table below.
Here are the options used for configuring column and row sizes.
minsize
| The column or row's minimum size in pixels. If there is nothing in the given column or row, it will not appear, even if you use this option. |
pad
| A number of pixels that will be added to the given column or row, over and above the largest cell in the column or row. |
weight
|
To make a column or row stretchable, use this
option and supply a value that gives the relative
weight of this column or row when distributing
the extra space. For example, if a widget w contains a grid layout, these lines
will distribute three-fourths of the extra space
to the first column and one-fourth to the second
column:
w.columnconfigure(0, weight=3)
w.columnconfigure(1, weight=1)
If this option is not used, the column or row
will not stretch.
|
Do you want to let the user resize your entire application window, and distribute the extra space among its internal widgets? This requires some operations that are not obvious.
It's necessary to use the techniques for row and column
size management, described in Section 4.3, “Configuring column and row sizes”, to make your Application widget's grid stretchable.
However, that alone is not sufficient.
Consider the trivial application discussed in Section 2, “A minimal application”, which contains only a button. If you run this application, and resize the window, the button stays the same size, centered within the window.
Here is a replacement version of the .__createWidgets() method in the minimal application. In
this version, the button
always fills all the available space.
def createWidgets(self):
top=self.winfo_toplevel()
top.rowconfigure(0, weight=1)
top.columnconfigure(0, weight=1)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.quit = Button ( self, text="Quit", command=self.quit )
self.quit.grid(row=0, column=0,
sticky=N+S+E+W)
|
The “top level window” is the outermost
window on the screen. However, this window is not
your |
| This line makes row 0 of the top level window's grid stretchable. |
| This line makes column 0 of the top level window's grid stretchable. |
|
Makes row 0 of the |
|
Makes column 0 of the |
|
The argument |
There is one more change that must be made. In the constructor, change the second line as shown:
def __init__(self, master=None):
Frame.__init__(self, master)
self.grid(sticky=N+S+E+W)
self.createWidgets()
The argument sticky=N+S+E+W to
self.grid() is necessary so that
the Application widget will
expand to fill its cell of the top-level window's grid.