What is the point of setting a size for a frame on Tkinter, if it will resize every time I add a new widget.
`
frame1 = Frame(self.MainWindow,width=600,height=100,bg='Blue')
frame1.grid(row=0,column=0)
#frame1.pack()
#Title
self.mainTitle = Label(frame1,text='Welcome')
self.mainTitle.grid(row=0,column=1,padx=60,pady=5)
#Back button
backButton = Button(frame1,text='Home',command=None)
backButton.grid(row=0,column=0,padx=60,pady=5)
nexButton = Button(frame1,text='Next',command=None)
nexButton.grid(row=0,column=2,padx=60,pady=5)
`
I do not know if there is any way to work with frames like divs in html.
What is the point of setting a size for a frame on Tkinter, if it will resize every time I add a new widget.
The vast majority of the time there is no advantage for setting a size on a frame. It can be useful in those cases when you have very strict requirements, but more often than not it's better to let tkinter size frames for you. It's very good at making responsive GUIs when you let it do all of the work of calculating sizes.
Related
Hi I made the GUI of this program in 1980x1080 and everything is fit to the window, but when I run the program on the other pc of resolution 1366x768 3/4 of the GUI is outside the display.
This is my constructor for the GUI
class Main:
def __init__(self,master = None):
self.master = master
self.master.geometry(str(master.winfo_screenwidth())+'x' +str(master.winfo_screenheight()))
self.master.state('zoomed')
self.variables_for_graphs()
self.variables_for_inputer()
self.variables_for_graphs_menu()
self.place_frames()
screenshot of the program in 1980x1080 display resolution:
screenshot of the program in 1366x768 display resolution:
I add scaling to the constructor
dpi = master.winfo_fpixels('1i')
factor = dpi / 72
master.tk.call('tk', 'scaling', factor)
it did not help
if anything else is need please comment
you can multiply every dimension in your GUI by the ratio between the current resolution and the original resolution, but that would result in very ugly look, instead of manually setting the sizes of each object you should let tkinter size your objects.
for grid layout (similar to yours) you have. Tk Geometry manager
widget1.grid(row=0,column=0,rowspan=2,sticky="NWSE")
widget2.grid(row=0,column=1,sticky="NWSE")
widget3.grid(row=1,column=1,sticky="NWSE")
parent_widget.rowconfigure((0,1),weight=1,minsize=200)
parent_widget.columnconfigure((0,1),weight=1,minsize=200)
to set your widgets to grow to fill all its master space, with a minimum size of 400x400.
for widgets that you pack you should use
widget.pack(expand=True,fill="both")
which will also make the child grow to fill its parent space, the size system may look intimidating at first, but once you start using it you can get any shape you want with it that scales the way you want.
avoid using place as you have to manually manage its size (unless you have an object that must be of fixed size and position like a logo or floating widget), and avoid filling numbers for sizes yourself, things that you can fill yourself are probably padding, buttons size (sometimes), and font size (under different dpi), you should have tkinter manage other dimensions in your GUI otherwise your GUI won't scale well.
I am trying to append an image to a frame I have. However, I have many frames within each other so I don't know what the dimensions of this frame are.
Is there any function or anything that will output the dimensions of the frame like "100x500", for example?
Thanks
Every widget has the methods winfo_width and winfo_height which return the current dimensions of the widget. You can also use winfo_reqwidth and winfo_reqheight to get the requested width and height. The two can be different if the size of the widget changes due to how it is managed (eg: when using sticky with grid, or fill with pack.
If the window has not yet actually been rendered, the width and height returned by winfo_width and winfo_height will be 1.
I am making a GUI with several buttons, text boxes,... in Python using TKinter. At this moment, all sizes of the components are fixed, so whenever the main frame is resized, the components do not adjust to the size of the main frame. As a result, when the frame reaches a certain size, components disappear.
Is there an easy solution that makes the sizes of the components dynamic and proportional to the size of the main frame?
The pictures below speak for themselfs...
Thanks in advance!
I've always found the pack() geometry manager quite ambiguous in terms of how it acts when widgets are added.
Here I have a simple code for creating a new frame within a much bigger parent frame. The frame size has been set to 300x300. The problem is that if I create a label with the pack() geometry manager within this frame, it will suppress the original frame size. Basically the frame will become as big as is the label.
If I use the place() geometry manager, then there is no problem and the frame stays at the original 300x300 size.
The question is - why does packing a label within the frame affects its size? And then what is the best way to avoid this problem and have everything fixed at the size as they are set?
class MainRightFrame(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.place(x=600, y=0)
self.config(height=300, width=300, bg='green')
label = Label(self, text='Left Frame')
label.place(x=10, y=10) # OPTION 1
# label.pack() # OPTION 2
why does packing a label within the frame affects its size?
Because that is how the packer is designed to work. It will shrink or grow to fit its contents, which is what you want 99.99% of the time.
For the canonical documentation for how pack works, see the official tcl/tk documentation here:
The packer algorithm
And then what is the best way to avoid this problem and have everything fixed at the size as they are set?
The best wait to avoid this "problem" is to use place. However, the way both pack and grid works makes it much easier then using place to create a responsive UI that can handle changes in font size, resolution, and the user manually resizing the window.
In over a couple decades of writing GUIs with python/tkinter and tcl/tk, I have never used place except for extremely special circumstances. Its simply too difficult to use for must common layouts.
If you absolutely insist on using pack or grid without this "shrink to fit" behavior, you can pass a false value to the pack_propagate or grid_propagate method of the containing frame (eg: self.pack_propagate(False)). In my experience this is very rarely the right solution.
To fix this, add the following line after the line beginning: self.config(...:
self.pack_propagate(0)
See here for a documentary explaining this.
As #KārlisRieksts noted, this approach does not work however if the frame (or other parent widget) is packed with place() geometry manager. The child widgets will then affect the size of the parent.
After lots of reading, I could not find solution for my problem.
I have made a quiz program using Tkinter and Python. I also used pack geometry manager everywhere. Window is not resizable, it's set to 960x540, and all widgets are precisely set in window using X and Y coordinates. Now, I'd like to make full screen option. But, when I turn it full screen, all widgets are moved in upper left corner (because they are set to X and Y coordinates using place manager). Any idea how could widgets 'stretch' when I turn window into full screen?
I know this could be accomplished using grid managed, but I would like to use pack manager instead.
I didn't post any code, because I don't think it would help. Please correct me if I'm wrong!
PS: Sorry for my weird English, and thank you a lot!
If you don't want to use grid you're going to need to use the place manager. A lot of people recommend against it because it's more complex, but I like the control it gives you over your GUI.
For example you can have a label that always stays in a relative position and has a relative width and height (in relation to the size of the screen)
newLabel = tk.Label(root)
newLabel.place(relwidth = 0.5, relheight = 0.2, relx = 0.25, rely = 0.4)
This creates a label that is always half the width of the root size, 20% of the root height, and is always centered in the screen.
These are two excellent tutorials on pack and place, and more importantly they are a great reference for the options that pack and place offer (scroll to the bottom of the page to see all the options and their descriptions). You may be able to get pack to do what you want, but I stick with place.
http://effbot.org/tkinterbook/pack.htm
http://effbot.org/tkinterbook/place.htm