You didn't way what the preferred behavior is, only that what it's doing is wrong. I don't know if this suggestion will do what you want or not.
As a rule of thumb, when you use grid you should always give at least one row and one column a weight for the parent containing the widgets being managed. While you do that for widgets in the container, you don't do it for the root window. Therefore, widgets inside the container might be resizing properly, but you won't see it because the container itself isn't resizing.
If you're only going to put a single widget inside another widget, I recommend using pack because you can do everything in a single line of code. Therefore, I recommend using pack rather than grid for the container itself:
container.pack(fill="both", expand=True)
Also, since your container seems to only have a single row and a single column, you probably don't want to give column 1 a weight.
Finally, you are also using grid to manage the widgets inside each page (N1, N2), but again, you are forgetting to give a weight to any rows or columns inside those frames.
You didn't way what the preferred behavior is, only that what it's doing is wrong. I don't know if this suggestion will do what you want or not.
As a rule of thumb, when you use grid you should always give at least one row and one column a weight for the parent containing the widgets being managed. While you do that for widgets in the container, you don't do it for the root window. Therefore, widgets inside the container might be resizing properly, but you won't see it because the container itself isn't resizing.
If you're only going to put a single widget inside another widget, I recommend using pack because you can do everything in a single line of code. Therefore, I recommend using pack rather than grid for the container itself:
container.pack(fill="both", expand=True)
Also, since your container seems to only have a single row and a single column, you probably don't want to give column 1 a weight.
Finally, you are also using grid to manage the widgets inside each page (N1, N2), but again, you are forgetting to give a weight to any rows or columns inside those frames.
The grid function keeps them where they are. You could use the pack function which could help you. It's just something that Tkinter doesn't do easily.
tkinter - Adjust widget size according to window size using grid geometry and screen size - Stack Overflow
python - How to create a self resizing grid of buttons in tkinter? - Stack Overflow
python - Tkinter grid and widget size - Stack Overflow
python - Resisze grid to fit tkinter window - Stack Overflow
Videos
You will need to apply grid_rowconfigure() and grid_columnconfigure() on, respectively, the rows and columns of the parent/main widget where you draw the children widgets.
Example:
Suppose on the main window you draw 2 buttons on the the first row and first 2 columns. You will need to apply the methods above like this:
main_window.grid_rowconfigure(0, weight=1) # For row 0
main_window.grid_columnconfigure(0, weight=1) # For column 0
main_window.grid_columnconfigure(1, weight=1) # For column 1
The columns and rows of the parent/main window have a weight grid option associated with them. This option, which is by default set 0 (don't expand to fill space), tells how much the row/column should grow if there is extra room in the master to fill.
Is this what you're looking for:
from tkinter import *
root = Tk()
label = Label(root, text="Hello world!", bg='cyan')
label.place(relwidth=0.5, relheight=0.5)
?
You need to configure the rows and columns to have a non-zero weight so that they will take up the extra space:
grid.columnconfigure(tuple(range(60)), weight=1)
grid.rowconfigure(tuple(range(30)), weight=1)
You also need to configure your buttons so that they will expand to fill the cell:
btn.grid(column=x, row=y, sticky="news")
This has to be done all the way up, so here is a full example:
from tkinter import *
root = Tk()
frame = Frame(root)
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
frame.grid(row=0, column=0, sticky="news")
grid = Frame(frame)
grid.grid(sticky="news", column=0, row=7, columnspan=2)
frame.rowconfigure(7, weight=1)
frame.columnconfigure(0, weight=1)
#example values
for x in range(10):
for y in range(5):
btn = Button(frame)
btn.grid(column=x, row=y, sticky="news")
frame.columnconfigure(tuple(range(10)), weight=1)
frame.rowconfigure(tuple(range(5)), weight=1)
root.mainloop()
@Vaughn Cato gave an excellent answer here. However, he has accidentally included a bunch of extraneous code in his example. Here is a cleaned up and more organized full example doing exactly what his example does.
from tkinter import *
#Create & Configure root
root = Tk()
Grid.rowconfigure(root, 0, weight=1)
Grid.columnconfigure(root, 0, weight=1)
#Create & Configure frame
frame=Frame(root)
frame.grid(row=0, column=0, sticky=N+S+E+W)
#Create a 5x10 (rows x columns) grid of buttons inside the frame
for row_index in range(5):
Grid.rowconfigure(frame, row_index, weight=1)
for col_index in range(10):
Grid.columnconfigure(frame, col_index, weight=1)
btn = Button(frame) #create a button inside frame
btn.grid(row=row_index, column=col_index, sticky=N+S+E+W)
root.mainloop()
Screenshots:
When it first opens (small):

After you maximize the window:

TODO
- [ ] 3 Aug. 2023: Update & modernize my example. Some changes occurred to the main answer that I should look at.
- [ ] 3 Aug. 2023: Remove
from tkinter import *, and useimport tkinterinstead, as it's bad practice to import all. It's better to see explicitly where each object comes from by using a module's namespace explicitly.
Hey guys!
I am currently making a GUI using tkinter. I am using the grid geometry manager for placing widgets on the window.
I want the window to be resizable and I want the widgets to expand as well, exactly how the code is running at the moment. But I dont want the widgets to scale to the window 1:1.
The pictures below will make you understand what I mean better:
Default size of the window When I expand it a little Full ScreenAs you noticed, the widgets are very far apart. I do not like this!
I want the widgets to grow far apart but not at this rate. Maybe half the rate at which the window is growing. At full screen, I want it to look something like this instead of the actual result. Forgive me I just overlapped 2 images in paint for visualizing it. There actually wont be 2 titlebars in the window. Only the outside titlebar will exist.
What I want the full screen window to look likePlease help me out with this, its urgent!!!!!
Link to the full code is here ...
https://drive.google.com/file/d/1zT4VYMRPz2WZHiSfQ3mdIY-OkJ6QrvY4/view?usp=sharing
