So I am creating a GUI and I am trying to make it so that everything fits on the screen appropriately. I've drawn a rough sketch of what I want each part of the GUI to look like an it's size, so I know the rough dimensions of everything.
The first problem I am having however is setting up the Left half of the screen.
So the Left half consists of a Frame, which we'll call MainFrame
, that consists of 2 Frames, which we'll call LabelFrame
and ButtonFrame
MainFrame
needs to be 385 pixels wide, and 460 pixels tall.LabelFrame
should be 375 pixels wide, and 115 pixels tall.ButtonFrame
needs to be 375 pixels wide, and 330 pixels tall.My issue is I have no idea how to set these sizes to the frames.
I've tried self.config(width = num, height = num)
obviously replacing num with the appropriate values, but that didn't do anything.
I know with the window itself there is a .geometry
method, but I haven't been able to find an equivalent for tk.Frame
The frame widget in Tkinter works like a container where we can place widgets and all the other GUI components. To change the frame width dynamically, we can use the configure() method and define the width property in it.
Click the Cogwheel icon at the bottom. From the Frame size drop-down list, select the resolution you need or choose Custom... and enter new values for width and height on the right. Click OK. Hit Convert.
The Frame widget is very important for the process of grouping and organizing other widgets in a somehow friendly way. It works like a container, which is responsible for arranging the position of other widgets. It uses rectangular areas in the screen to organize the layout and to provide padding of these widgets.
To position the Tkinters widgets, we can use place() geometry manager, where we will specify the anchor property. It can take (NW, N, NE, W, CENTER, E, SW, S, SE) as the position of the widget.
Use grid_propagate(0)
or pack_propagate(0)
, depenending on geometry manager in use. 0
is just False
, that told tkinter to shut off geometry propagation.
By default, propagation is on, and a container grows/shrinks to be just big enough to hold its contents.
And I assume that your desired layout something like this:
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
root = tk.Tk()
MainFrame = tk.Frame(root, width=385, height=460, relief='raised', borderwidth=5)
LabelFrame = tk.Frame(MainFrame, width=375, height=115, relief='raised', borderwidth=5)
ButtonFrame = tk.Frame(MainFrame, width=375, height=330, relief='raised', borderwidth=5)
some_label = tk.Label(LabelFrame, text='Simple Text')
some_button = tk.Button(ButtonFrame, text='Quit', command=root.destroy)
for frame in [MainFrame, LabelFrame, ButtonFrame]:
frame.pack(expand=True, fill='both')
frame.pack_propagate(0)
for widget in [some_label, some_button]:
widget.pack(expand=True, fill='x', anchor='s')
root.mainloop()
and with grid
manager the difference only in a loop section (note sticky
and row/column configure
):
...
for frame in [MainFrame, LabelFrame, ButtonFrame]:
# sticky='nswe' acts like fill='both'
frame.grid(sticky='nswe')
frame.rowconfigure(0, weight=1)
frame.columnconfigure(0, weight=1)
frame.grid_propagate(0)
for widget in [some_label, some_button]:
# sticky='wse' acts like fill='x' + anchor='s'
widget.grid(sticky='wse')
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
...
While I never recommend building a UI to a fixed pixel size, if that's what you're doing than the simplest solution is to use place
. place
gives you absolute control over the location and size of widgets, and will not cause frames to grow or shrink to fit their contents.
import tkinter as tk
root = tk.Tk()
root.geometry("800x480")
mainframe = tk.Frame(root, background="bisque")
labelframe = tk.Frame(mainframe, background="pink")
buttonframe = tk.Frame(mainframe, background="yellow")
mainframe.place(x=0, y=0, anchor="nw", width=385, height=460)
labelframe.place(x=0, y=0, anchor="nw", width=375, height=115)
buttonframe.place(x=0, y=116, anchor="nw", width=375, height=330)
root.mainloop()
You will page a huge penalty if you ever need to run this on a device with a different resolution or different fonts because it will be a nightmare to rearrange everything. Even if you're targeting a fixed size outer window, I personally recommend using grid
or pack
on the inside and using relative sizes (eg: make the mainframe fill half the width and all of the height)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With