[Tutor] Tkinter grid manager

Alan Gauld alan.gauld at yahoo.co.uk
Tue Feb 22 19:45:39 EST 2022


On 23/02/2022 00:11, Phil wrote:
> I think I've misunderstood the purpose of the grid manager. 

Its purpose is quite simple, to put widgets into boxes
in a grid. The grid can be as big or little as needed.

> The pack manager does exactly what I have in mind, 

It's very common to use both in the same app.
pack is great for positioning the bigger panels/frames
within your overall app. grid is great for positioning
widgets within a frame or panel.

> Looking at the following abbreviated code, the "on" and "off" buttons 
> are always located on row 0 and column 0 no matter what the row and 
> column settings are. 

They shouldn't be. And its very unusual to position two
widgets in the same grid cell!

> Adding a third button means that I can now locate a 
> button on column 3, which does make sense. 

> pady does place the buttons where I'd like them but I don't think that's 
> the correct use of the grid manager.

Almost certainly not.

> I'd like to locate the "on" and "off" buttons at the bottom right corner 

So the columns should be N-1 and N respectively
And the row should be M.
for an MxN grid.
The cells number from top-left to bottom-right.

> is more suited to placing a label beside a widget rather that the exact 
> placement of a widget.

Neither Pack nor grid are good at exact placement, for that you
use the place() manager. But only if you turn of resizing of
your app, otherwise it will all go horribly wrong very quickly.
Both pack() and grid() provide relative placement which is
dynamically calculated as the window is moved/resized.
You can also use the form() manager which is specifically
designed for building business app style forms and dialogs
with label/entry pairs etc. (but I confess I've never used
it beyond following a tutorial)

> import tkinter as tk
> 
> 
> class Root(tk.Tk):
>      def __init__(self):
>          super().__init__()
>          self.title("Template")
>          self.geometry("300x200")
> 
>          self.frame = tk.Frame(bg='light blue')
> 
>          self.frame.grid(row=0, column=0, sticky='nsew')    # I found 
> that I had to add these lines so that
>          self.grid_rowconfigure(0, weight = 1)    # the frame would fill 
> the main window.
>          self.grid_columnconfigure(0, weight = 1)                 # 
> Could there be a problem here?

You are basically creating a single frame widget that fills
the main window, so I'd probably just use pack() here and
fill/expand the widget to fill the window.

Then you can use grid to manage the widgets inside the frame
if you wish.


>          self.create_widgets()
> 
>      def create_widgets(self):
> 
>          self.on_button = tk.Button(self.frame,
>                                    text="On",
>                                    command=self.on_on_button_press)
> 
>          self.off_button = tk.Button(self.frame,
>                                     text="Off",
> command=self.on_off_button_press)
> 
>          self.on_button.grid(row=5, column=0, padx=10, pady=10) # row 
> can be any value, the result is
>          self.off_button.grid(row=5, column=1, padx=10, pady=10) # 
> always row 0.

That should put the two buttons in the bottom-left corner.


> 
>          self.another_button = tk.Button(self.frame,
>                                     text="another")
> 
>          self.another_button.grid(row=8, column=3, padx=0, pady=60)

But this will now be below them.

But notice you don't have anything in rows 0-4 or 6 and 7.
Thus the grid will be empty and it will look like you only
have 2 rows, with on/off on the top one and another on the
bottom. An empty row has no size.


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list