I'm trying to set a minimum width to a column in a grid, but it is having no effect:
labelProjectId = Tkinter.Label(frame, text="Id", background='white', borderwidth=1, relief="solid")
abelProjectId.grid(row=row, column=0, sticky=("W", "E"))
labelProjectId.grid_columnconfigure(0, minsize=200) # ???
What am I doing wrong?
You are setting the minimum width for the grid inside the label. If you want to affect the column that the label is in, you must call grid_columnconfigure on its master.
Related
A Frame that has 2 rows and 1 column can be weighted. From my understanding, this will set the growth from some arbitrary position to be proportional. So something like:
self.grid_columnconfigure(0, weight=1)
self.grid_rowconfigure(0, weight=1)
self.grid_rowconfigure(1, weight=10)
# # ============ frame_header ============
self.frame_header = tk.Frame(master=self, bg='red')
self.frame_header.grid(row=0, column=0, sticky="nsew")
self.frame_header.grid_rowconfigure(0, weight=1)
self.frame_header.grid_columnconfigure(0, weight=1)
self.label1 = tk.Label(master=self.frame_header, text = 'HEADER', bg='red')
self.label1.grid(row=0, column=0, sticky="nsew")
# # ============ frame_main ============
self.frame_main = tk.Frame(master=self)
self.frame_main.grid(row=1, column=0, sticky="nsew")
self.frame_main.grid_rowconfigure(0, weight=1)
self.frame_main.grid_columnconfigure(0, weight=1)
self.label2 = tk.Label(master=self.frame_main, text = 'MAIN')
self.label2.grid(row=0, column=0, sticky="nsew")
will yield a window in which the top half and bottom half are weighted differently. But they are not actually in a 1:10 proportion. This is evident that as the window is resized, the proportion changes:
So I'm sure there's some other flag I have to set, or some other aspect of the layout manager I'm missing, but I have not been able to find anything that addresses this.
From my understanding, this will set the growth from some arbitrary position to be proportional
Not so much arbitrary, but rather initial. Grid will compute the layout based on the requested size of the widgets. If there is any unallocated space left over, the space will be allocated to each row or column proportional to its weight.
If you set the uniform option to be the same string for a group of rows or columns along with a weight, they will all be sized proportional to their weights.
This is from the official grid documentation:
The -uniform option, when a non-empty value is supplied, places the row in a uniform group with other rows that have the same value for -uniform. The space for rows belonging to a uniform group is allocated so that their sizes are always in strict proportion to their -weight values
The tcl/tk man pages have a section titled The Grid Algorithm which explains exactly how grid works.
My code is as follows:
Code
but = Button(root, text="Translate!", command= lambda : gtrans(tren.get()))
but.grid(row=2, column=2, padx=5, pady=5)
but2 = Button(root, text="Clear", command = lambda: reset())
but2.grid(row=2, column=3, padx=5, pady=5)
And my output is as follows:
This is what appears when i extend a 300x300 window
Please Help
If you follow your pastebin, you can see that both your label and entry are also in col = 2 (i.e. same as 'Translate!' button). So the issue is not a big gap between columns(the gap between Entry window and the 'Clear' button is rather small). The issue is the width of col2 is fitting your label.
What you could do:
Add columnspan = 2 to both Entry and Label (thus these elements will
span over column 2 and column 3) as lab.grid(row=0, column=2, columnspan = 2) and tren.grid(row=1, column=2, columnspan = 2)
Following this answer you could add sticky = 'E' on your
'Translate!' button to move it to the right edge of column 2, thus
reducing gap between the two buttons (I'm not sure if it would look
the best, but it depends how you want it to be)
I'd like to create three text areas in a tkinter window and make them dinamically resizable. I thought that one solution was to pass the width and height parameters in pixels (such as height=int(win_height/2)), but as I read it isn't possible, in fact the width and height parameters in a tk.Text widget are calculated by characters for each line and column. I've also tried to pass the width and height parameters in percentages (such as height=50%) but it returns me a syntax error.
I've been trying to find out a solution for this problem in the net, and the best code I've found is this:
import tkinter as tk
root = tk.Tk()
root.geometry("500x500")
# Text Box
first_textbox = tk.Text(root, width=25, height=10, bg='yellow')
second_textbox = tk.Text(root, width=25, height=10, bg='blue')
third_textbox = tk.Text(root, width=50, height=20, bg='red')
# Packing
first_textbox.grid(column=1, row=1)
second_textbox.grid(column=1, row=2)
third_textbox.grid(column=2, row=1, rowspan=2)
root.mainloop()
By running this code I obtain a window with three different text areas which aren't dinamically resizabled and which take more space than the actual window width. I hope you can help me.
Sorry for any English mistake, it is my second lenguage
grid has several documented parameters to help you do what you want. You simply need to use them.
By default, grid won't give widgets any extra space -- they take up only the space they need and no more. If you widgets to be allocated extra space, you have to explicitly arrange for that.
For example, if you want all widgets to grow and shrink equally, you need to configure the rows and columns to have an equal weight greater than zero. That will tell grid how to allocate any extra space when the window is bigger than the size requested by all of the widgets.
For example:
root.grid_rowconfigure((1,2), weight=1)
root.grid_columnconfigure((1,2), weight=1)
That just tells grid what to do with extra space. If instead, you want two or more rows or columns to have exactly the same size, you can use the uniform option to tell grid that you want the rows or columns to have a uniform (identical) size.
For example, if you want both columns 1 and 2 to have the same width, you can give each column the same value for the uniform option. Note: the value passed to uniform can be anything you want. The important thing is that they are configured to have the same value.
root.grid_columnconfigure((1, 2), uniform="equal")
That alone won't solve the problem. You also must tell grid that you want the widgets to fill the space given to them. You do that with the sticky parameter, which tells grid to "stick" the widget to one or more sides of the allocated space.
To get the widgets to fill all allocated space you can give the string "nsew" which stands for "north, south, east, and west" which represent the four sides of the given space.
first_textbox = tk.Text(root, width=25, height=10, bg='yellow')
second_textbox = tk.Text(root, width=25, height=10, bg='blue')
third_textbox = tk.Text(root, width=50, height=20, bg='red')
I want to create a GUI with tkinter in python using grid-Method and grid_columnconfigure/grid_rowconfigure.
Unfortunately, this is not working inside a Frame.
How can I get this work?
from tkinter import *
master = Tk()
master.state('zoomed')
f = Frame(master, width=800, height=400)
Label1 = Label(f, text='Label 1')
Label2 = Label(f, text='Label 2')
f.grid_columnconfigure(0, weight=1)
f.grid_columnconfigure(2, weight=1)
f.grid_columnconfigure(4, weight=1)
Label1.grid(row=0, column=1)
Label2.grid(row=0, column=3)
f.pack()
master.mainloop()
ADDITIONAL QUESTION:
I got great answers, all is working fine with pack-Manager.
But how could I do this if using grid-Manager?
The grid_columnconfigure is working fine. The problem is that your frame will by default set its size to the smallest possible size to fit the labels. Since empty columns don't have a size, the frame will be just wide enough to hold the two labels.
This will be easy to visualize if you give frame a distinctive color during development. It also sometimes helps to give the frame a visual border so you can see its boundaries.
While I don't know what your ultimate goal is, you can see the spaces between the column if you have the frame fill the entire window:
f.pack(fill="both", expand=True)
If you want to use grid instead of pack, you have to do a bit more work. In short, put the frame in row 0 column 0, and give that row and column a non-zero weight so that grid will give all unused space to that row and column.
f.grid(row=0, column=0, sticky="nsew")
master.grid_rowconfigure(0, weight=1)
master.grid_columnconfigure(0, weight=1)
If you want to force the window to be a specific size, you can use the geometry method of the master window:
master.geometry("800x400")
I would expect the text area that the below code produces to take up half of the screen because the weights of the columns are equal.
Why does the text area take up about 2/3 of the screen instead and how do I get the text area to only take up half the screen?
from tkinter import *
root = Tk()
root.wm_state('zoomed')
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
root.rowconfigure(0, weight=1)
root.configure(bg='red')
info_frame = Frame(root)
info_frame.grid(row=0, column=1, sticky="nsew")
info_frame.columnconfigure(0, weight=1)
info_frame.rowconfigure(0, weight=1)
user_frame = Frame(root, bg='blue')
user_frame.grid(row=0, column=0, sticky="nsew")
user_frame.columnconfigure(0, weight=1)
user_frame.rowconfigure(0, weight=1)
user_frame.rowconfigure(1, weight=1)
button_frame = Frame(user_frame)
button_frame.grid(row=0, column=0, sticky="nsew")
entry_frame = Frame(user_frame)
entry_frame.grid(row=1, column=0, sticky="nsew")
info_display = Text(info_frame, state=DISABLED)
info_display.grid(row=0, column=0, sticky="nsew")
scrollbar = Scrollbar(info_frame)
scrollbar.grid(row=0, column=1, sticky="nsew")
light_label = Label(entry_frame, text='Light').grid(row=0, column=0)
light_entry = Entry(entry_frame).grid(row=0, column=1)
current_label = Label(entry_frame, text='Current').grid(row=1, column=0)
current_entry = Entry(entry_frame).grid(row=1, column=1)
button1 = Button(button_frame, text='button1').grid(row=0, column=0)
button2 = Button(button_frame, text='button2').grid(row=0, column=1)
button3 = Button(button_frame, text='button3').grid(row=1, column=0)
button4 = Button(button_frame, text='button4').grid(row=1, column=1)
root.mainloop()
The weight tells tkinter how to allocate extra space, it's not a mechanism to guarantee that columns or rows have the same size.
Let's say you place a 100 pixel wide widget in column 0, and a 200 pixel wide widget in column 1, and you give both columns equal weight. The GUI will naturally try to be 300 pixels wide, because that's what you requested.
If you make the window larger (either through interactive resizing, by using the geometry method, or by zooming the window), tkinter will use the weight to decide how to allocate extra space.
For example, if you force the GUI to be 500 pixels wide, there are 200 unallocated pixels. Given that each column has the same weight, 100 pixels will go to each column, making one column 200 pixels and the other column 300. Thus, even though they have the same weight, they won't have the same size.
If you want columns to have an identical width, you can use the uniform option to make the columns part of a uniform group. Within that group, all columns will have the same width.
For example, this will guarantee that each column takes up half the space (by virtue of there being only two columns with weight, and they are the same size, by definition they must take up half the window)
root.columnconfigure(0, weight=1, uniform="half")
root.columnconfigure(1, weight=1, uniform="half")
Note: you can use any string you want in place of "half" -- the only critiera is that all columns with the same value will have the same width.
Grid weights distribute extra space. See reference.
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)
The default size of the text widget is much bigger than the default size of the other stuff. If you want more equal columns, you must grow the other stuff and shrink the text.