TKinter: lost alignment between frame and root - python

I am running into a curious problem. I have a small grid (8 rows, 5 columns). Root with a couple of frames. Most run fine. Four fields of the the top row (1 in my case, I do not use 0) have a text and must have the same color continuously. I could not realise this in root itself so I made a frame (text=""), with labels. That gives the desired look apart from the fact that all the texts are concatenated at the left and no longer above the gridfields below.
The code is realy very simple but I expect it will be requested anyway so here is the relevant part:
# Top frame
top_frame=LabelFrame(root, text= "", bg=top_line_color)
top_frame.grid(row =1, column=0, sticky=W+E, columnspan=5)
# Fixed labels:
Label(top_frame, text="Anten", font=fnt, bg=top_line_color).grid(row=1,
column=0)
Label(top_frame, text="Antenna", font=fnt, bg=top_line_color).grid(row=1,
column=1)
Label(top_frame, text="Corr.", font=fnt, width=4,
bg=top_line_color).grid(row=1, column=3)
Label(top_frame, text="Move", font=fnt, width=4,
bg=top_line_color).grid(row=1, sticky=W, column=4)
Label(root, text="Azimuth:", justify=RIGHT, font=fnt).grid(row=2, sticky=W)
Label(root, text="Elevation:", justify=RIGHT, font=fnt).grid(row=3,
sticky=W)
Label(root, text="Location:",justify=RIGHT, font=fnt).grid(row=4, sticky=W)
Label(root, text=acemedat.myloc, font=fnt).grid(row=4, column=1)
Label(root, text="Dat/Tim:", justify=RIGHT, font=fnt).grid(row=4, column=2)
Label(root, text="Moon distance (km):", font=fnt).grid(row=5, columnspan=2,
sticky=W)
The labels are followed by data fields (in root as well). They comply with the grid without problem.
What can I do to to align the frame fields with the root fields?
Many thanks in advance,
Harke

If you want everything to line up in a grid, the easiest solution is to put them all in the same frame. If you use the sticky attribute for the fixed labels, you can have a solid, unbroken color. Depending on your system, you might need to change the labels to have a borderwidth and/or highlightthickness of zero. If you want the labels to be left-aligned, you can do that with the anchor attribute of the labels.
For example:
from tkinter import *
root = Tk()
fnt = ("Helvetica", "12")
top_line_color = "bisque"
# Fixed labels:
Label(root, text="Anten", font=fnt, bg=top_line_color,
anchor="w").grid(row=0, column=0, sticky="nsew")
Label(root, text="Antenna", font=fnt, bg=top_line_color,
anchor="w").grid(row=0, column=1, sticky="nsew")
Label(root, text="Corr.", font=fnt, width=4, bg=top_line_color,
anchor="w").grid(row=0, column=2, sticky="nsew")
Label(root, text="Move", font=fnt, width=4, bg=top_line_color,
anchor="w").grid(row=0, column=3, sticky="nsew")
Label(root, text="Azimuth:", justify=RIGHT, font=fnt).grid(row=2, sticky=W)
Label(root, text="Elevation:", justify=RIGHT, font=fnt).grid(row=3, sticky=W)
Label(root, text="Location:",justify=RIGHT, font=fnt).grid(row=4, sticky=W)
Label(root, text="acemedat.myloc", font=fnt).grid(row=4, column=1)
Label(root, text="Dat/Tim:", justify=RIGHT, font=fnt).grid(row=4, column=2)
Label(root, text="Moon distance (km):", font=fnt).grid(row=5, columnspan=2, sticky=W)
root.mainloop()

Related

Aligning entries/buttons with tkinter

I've been trying to align the entries and buttons on this password manager I built for a while now but haven't been able to find a solution that works.
I tried changing the width, columnspan, and coordinates but it doesn't seem to work.
I want the password entry to be aligned just like the other two but with a lower width so that the generate button does not go over. I also want the add button to be aligned equally with the row and column.
window = Tk()
window.title("Password Manager")
window.config(padx=50, pady=50)
canvas = Canvas(width=200, height=200)
my_pass_img = PhotoImage(file="logo.png")
canvas.create_image(100, 100, image=my_pass_img)
canvas.grid(column=1, row=0)
web_label = Label(text="Website:", fg="black")
web_label.grid(row=1, column=0)
user_label = Label(text="Email/Username:", fg="black")
user_label.grid(row=2, column=0)
pass_label = Label(text="Password:", fg="black")
pass_label.grid(row=3, column=0)
web_entry = Entry(width=35)
web_entry.grid(row=1, column=1, columnspan=2)
web_entry.focus()
user_entry = Entry(width=35)
user_entry.grid(row=2, column=1, columnspan=2)
user_entry.insert(0, "-#gmail.com")
pass_entry = Entry(width=30)
pass_entry.grid(row=3, column=1)
generate_button = Button(text="Generate Password", fg="black", command=generate_password)
generate_button.grid(row=3, column=2)
add_button = Button(width=36, text="Add", fg="black", command=save)
add_button.grid(row=4, column=1, columnspan=2)
window.mainloop()
Grid
When using grid to setup your widgets, the entire window is divided into individual cells based on the number of columns and rows you've specified. Although you can control the individual sizes of widgets, the overall size it can take will be limited by your choice of column- and rowwidth, as well as column- and rowspan.
Sticky
You can use the sticky attribute in grid to set the side of the column you want your widgets to 'stick' to.
The stickiness is set by choosing one of the 8 directions on a compass:
N (north): stick to top of cell
S (south): bottom
E (east): right
W (west): left
NW, NE, SW, SE: top-left, top-right, bottom-left, bottom-right corners respectively.
There are also two bonus stickiness options:
NS: stretch your widget from top to bottom of the sell, but keep it centered horizontally
EW: stretch from left to right of the cell, but centered vertically.
Padding
To increase legibility, you can add padding above and below, and to the sides, of your widgets using the padx and pady attributes (measured in pixels).
So if you set stickyness to "W" with a horizontal padding padx=5, the widget position is offset from the cell boundary by 5 pixels.
Combining it in your example
To align the entries, set their sticky attribute to "W", or tk.W, to algin on left side of cell.
If you want to align labels on the right set sticky="E".
You can reduce the columnspan too of the entries, if you don't need them to be extra large. The resulting changes to grid are thus:
canvas.grid(column=1, row=0)
# Label widgets: set sticky to 'East'
web_label.grid(row=1, column=0, sticky='E')
user_label.grid(row=2, column=0, sticky='E')
pass_label.grid(row=3, column=0, sticky='E')
# Entry widgets
web_entry.grid(row=1, column=1, columnspan=1, sticky='WE')
user_entry.grid(row=2, column=1, columnspan=1, sticky=tk.EW) # Note flag is available as tkinter attribute
# Password entry: align on left-hand side
pass_entry.grid(row=3, column=1, sticky='W')
# Align button to right side of 3rd column
generate_button.grid(row=3, column=2,sticky='E')
# Can either align in middle column...
add_button.grid(row=4, column=1, columnspan=1, sticky="WE")
#... or in middle of page
add_button.grid(row=4, column=0, columnspan=3, sticky="WE")
Bonus
Apply padding (or sticky) to all widgets in a frame or window:
for child in window.winfo_children():
child.grid_configure(padx=3, pady=3)
# child.grid_configure(sticky='W')
You can use sticky option to put the widget in a grid cell at "n" (north), "s" (south), "e" (east) and "w" (west). If not specify, it is by default is "" which will put the widget at the center of the cell.
For your case, add sticky="w" to all the labels and entries, and sticky="e" to the "Add" button:
from tkinter import *
def generate_password():
pass
def save():
pass
window = Tk()
window.title("Password Manager")
window.config(padx=50, pady=50)
canvas = Canvas(window, width=200, height=200)
my_pass_img = PhotoImage(file="logo.png")
canvas.create_image(100, 100, image=my_pass_img)
canvas.grid(column=1, row=0)
web_label = Label(window, text="Website:", fg="black")
web_label.grid(row=1, column=0, sticky="w")
user_label = Label(window, text="Email/Username:", fg="black")
user_label.grid(row=2, column=0, sticky="w")
pass_label = Label(window, text="Password:", fg="black")
pass_label.grid(row=3, column=0, sticky="w")
web_entry = Entry(window, width=35)
web_entry.grid(row=1, column=1, columnspan=2, sticky="w")
web_entry.focus()
user_entry = Entry(window, width=35)
user_entry.grid(row=2, column=1, columnspan=2, sticky="w")
user_entry.insert(0, "-#gmail.com")
pass_entry = Entry(window, width=30)
pass_entry.grid(row=3, column=1, sticky="w")
generate_button = Button(window, text="Generate Password", fg="black", command=generate_password)
generate_button.grid(row=3, column=2)
add_button = Button(window, width=36, text="Add", fg="black", command=save)
add_button.grid(row=4, column=1, columnspan=2, sticky="e")
window.mainloop()
Result:
You can play around with different values or combinations of them of the sticky option to see the different effects.
Note also that it is better to specify the parent of those widgets.

Columnspan Widget Throwing Off Columns

I'm having trouble getting my first "None" checkbox widget where I want it. Here is a link to a screenshot.
I'm trying to get the "None" checkbox widget to be directly to the right of the Entry widget. The bottom rows containing spinbox widgets are contained within a LabelFrame widget located at row=7, column=2 that has a columnspan of 2. My first checkbox widget is located at row=5, column=3 with sticky='w'. Why then isn't it up against the Entry widget at row=5, column=2 since I gave the LabelFrame a columnspan of 2?
Here is my code:
tk.Label(GUI, text='label 1').grid(row=0, sticky='w')
tk.Label(GUI, text='label 2').grid(row=1, sticky='w')
tk.Label(GUI, text='label 3').grid(row=2, sticky='w')
tk.Label(GUI, text='label 4').grid(row=3, sticky='w')
tk.Label(GUI, text='label 5').grid(row=4, sticky='w')
tk.Label(GUI, text='label 6').grid(row=5, sticky='w')
tk.Label(GUI, text='label 7').grid(row=6, sticky='w')
tk.Label(GUI, text='label 8').grid(row=7, sticky='w')
tk.Label(GUI, text='label 9').grid(row=8, sticky='w')
tk.Label(GUI, text='$').grid(row=2, column=1, sticky='w')
tk.Label(GUI, text='$').grid(row=3, column=1, sticky='w')
tk.Label(GUI, text='$').grid(row=4, column=1, sticky='w')
tk.Label(GUI, text='9999').grid(row=2, column=2, sticky='w')
input1 = tk.Entry(GUI, width=10)
input2 = tk.Entry(GUI, width=10)
input3 = tk.Entry(GUI, width=10)
button_input = tk.Checkbutton(GUI, text='None')
input5 = tk.Entry(GUI, width=10)
date_field = tk.LabelFrame(GUI)
scheduled_start_month_input = tk.Spinbox(date_field, from_=1, to=12, width=2)
scheduled_start_day_input = tk.Spinbox(date_field, from_=1, to=31, width=2)
scheduled_start_year_input = tk.Spinbox(date_field, from_=2018, to=2025, width=4)
scheduled_start_hour_input = tk.Spinbox(date_field, from_=0, to=23, width=2)
scheduled_start_minute_input = tk.Spinbox(date_field, from_=0, to=59, width=2)
start_on_launch_option = tk.Checkbutton(date_field, onvalue=True, offvalue=False, text='On Launch')
scheduled_stop_month_input = tk.Spinbox(date_field, from_=1, to=12, width=2)
scheduled_stop_day_input = tk.Spinbox(date_field, from_=1, to=31, width=2)
scheduled_stop_year_input = tk.Spinbox(date_field, from_=2018, to=2025, width=4)
scheduled_stop_hour_input = tk.Spinbox(date_field, from_=0, to=23, width=2)
scheduled_stop_minute_input = tk.Spinbox(date_field, from_=0, to=59, width=2)
scheduled_stop_none = tk.Checkbutton(date_field, onvalue=True, offvalue=False, text='None')
input1.grid(row=3, column=2, sticky='w')
input2.grid(row=4, column=2, sticky='w')
input3.grid(row=5, column=2, sticky='w')
button_input.grid(row=5, column=3, sticky='w')
input5.grid(row=6, column=2, sticky='w')
date_field.grid(row=7, column=2, rowspan=2, columnspan=2, sticky='w')
scheduled_start_month_input.grid(column=0)
tk.Label(date_field, text='/').grid(column=1, row=0)
scheduled_start_day_input.grid(column=2, row=0)
tk.Label(date_field, text='/').grid(column=3, row=0)
scheduled_start_year_input.grid(column=4, row=0)
tk.Label(date_field, text=' ').grid(column=5, row=0)
scheduled_start_hour_input.grid(column=6, row=0)
tk.Label(date_field, text=':').grid(column=7, row=0)
scheduled_start_minute_input.grid(column=8, row=0)
start_on_launch_option.grid(row=0, column=9)
scheduled_stop_month_input.grid(column=0)
tk.Label(date_field, text='/').grid(column=1, row=1)
scheduled_stop_day_input.grid(column=2, row=1)
tk.Label(date_field, text='/').grid(column=3, row=1)
scheduled_stop_year_input.grid(column=4, row=1)
tk.Label(date_field, text=' ').grid(column=5, row=1)
scheduled_stop_hour_input.grid(column=6, row=1)
tk.Label(date_field, text=':').grid(column=7, row=1)
scheduled_stop_minute_input.grid(column=8, row=1)
scheduled_stop_none.grid(column=9, row=1, sticky='w')
tk.Button(GUI, text='Launch').grid(row=9, sticky='w')
GUI.mainloop()
The problem is that the 2nd column is wider than you think it is. To see it, change the line where you add the input widget to the grid so that it looks like this:
input3.grid(row=5, column=2, sticky='ew')
You'll see that the checkbutton is in fact as far left as it can go, and it is the column to its left that is responsible for all of the extra space.
The reason is because the datefield widget spans two columns, but those two columns aren't wide enough to hold the datefield. grid has to add extra space to the columns so that the widget will fit.
If you want the second column to stay a fixed size and have column 3 to be the one that grows and shrinks, you have to give column 3 a non-zero weight so that grid can allocate all extra space to that column.
You can do that by adding this line of code somewhere:
GUI.grid_columnconfigure(3, weight=1)
Another solution would be to add the weight to an invisible column 4, and then have datefield span three columns instead of two. That will cause columns 2 and 3 to retain their natural size, and any extra space would be given to an empty column.
GUI.grid_columnconfigure(4, weight=1)
date_field.grid(row=7, column=2, rowspan=2, columnspan=3, sticky='w')
Add following code:
GUI.grid_columnconfigure(3, weight=1)
It means that column 3 would occupy all the place it can get. Your/default weight is 0. and that means Checkbutton instance is wide just as "None" text is, so sticky w equals sticky e equals sticky we or wens. If you set the weight to 1 then your sticky argument actually takes place.

Python Tkinter grid spacing of widgets and LablelFrames not right

I am designing a simple GUI in Python 2.7 Tkinter, but I can't get things to spread out as I want them. I have managed to get my various widgets roughly where I want them, however I can't seem to force spacing out and things are a little bunched up.
I have also tried to draw 3 LabelFrames to separate the window out, but widgets seem to fall over the LabelFrames. I am wondering how I can space this out a little better. The grid system seems to allow things to bunch up and ignores blank rows and columns as far as I can see.
from Tkinter import *
import Tkinter, Tkconstants, tkFileDialog, tkMessageBox
class FileZap():
def __init__(self, root):
root.title("TestGUI")
root.geometry("860x450")
self.topFrame = LabelFrame(root, text="Top Area")
self.topFrame.grid(row=1, column=1, rowspan=6, columnspan=7, padx=5, pady = 5, sticky="NSEW")
self.listbox1 = Listbox(root, width=50, selectmode="multiple")
self.listbox1.grid(row=3, column=2)
self.scrollbar = Scrollbar(orient=VERTICAL, command=self.listbox1.yview)
self.listbox1.config(yscrollcommand=self.scrollbar.set)
self.scrollbar.grid(row=3, column=3, sticky="ns")
self.listbox2 = Listbox(root, width=50)
self.listbox2.grid(row=3, column=4)
self.selectLabel = Label(root, text="Select a folder: ")
self.selectLabel.grid(row=3, column=1)
self.user1 = Entry(root, width="50")
self.user1.grid(row=2, column=2)
self.browse = Button(root, text="Browse")
self.browse.grid(row=2, column=3)
self.addItems = Button(root, text="Add to Selection")
self.addItems.grid(row=4, column=2)
self.clearItems = Button(root, text="Clear Selection")
self.clearItems.grid(row=4, column=4)
self.leftFrame = LabelFrame(root, text="Left Area")
self.leftFrame.grid(row=5, column=1, rowspan=6, columnspan=3, padx=5, pady = 5, sticky="NSEW")
self.replaceInLable = Label(root, text="String to replace: ")
self.replaceOutLable = Label(root, text="New string: ")
self.replaceInLable.grid(row=7, column=1)
self.replaceOutLable.grid(row=7, column=2)
self.replaceIn = Entry(root, width="20")
self.replaceOut = Entry(root, width="20")
self.replaceIn.grid(row=8, column=1)
self.replaceOut.grid(row=8, column=2)
self.replace = Button(root, text="Replace")
self.replace.grid(row=8,column=3)
self.rightFrame = LabelFrame(root, text="Right Area")
self.rightFrame.grid(row=5, column=4, rowspan=6, columnspan=3, padx=5, pady = 5, sticky="NSEW")
self.quit = Button(root, text="Exit", command=root.quit)
self.quit.grid(row=9, column=6)
root = Tkinter.Tk()
file_zap = FileZap(root)
root.mainloop()
I have tried various alterations but can't nail it! Any help would be much appreciated.
First, the columns / row adapt to there content so an empty one as a zero height/width. If you want to put space between your widgets use the padx and pady options in the .grid method. They can take either one number which will give the padding on both sides or a couple of numbers giving the padding on each side.
Secondly, if you want your widgets to be inside a LabelFrame, you need to create them with this LabelFrame as master instead of the main window.
from Tkinter import LabelFrame, Tk, Button, Label
root = Tk()
# make row 0 resize with the window
root.rowconfigure(0, weight=1)
# make column 0 and 1 resize with the window
root.columnconfigure(0, weight=1)
root.columnconfigure(1, weight=1)
# create LabelFrames
top_frame = LabelFrame(root, text="top")
left_frame = LabelFrame(root, text="left")
right_frame = LabelFrame(root, text="right")
top_frame.grid(row=0, column=0, columnspan=2, padx=10, pady=(10,4), sticky="nsew")
left_frame.grid(row=1, column=0, padx=(10,4), pady=4, sticky="nsew")
right_frame.grid(row=1, column=1, padx=(4,10), pady=4, sticky="nsew")
#create widgets inside top_frame
Label(top_frame, text="I'm inside top_frame").pack()
Button(top_frame, text="Top").pack()
#create widgets inside left_frame
Label(left_frame, text="I'm inside left_frame").pack()
Button(left_frame, text="Left").pack()
#create widgets inside top_frame
Label(right_frame, text="I'm inside right_frame").pack()
Button(right_frame, text="Right").pack()
Button(root, text="Quit", command=root.destroy).grid(row=2, column=0,
columnspan=2, pady=10)
root.mainloop()

Python3.5 -configure a single cell to expand instead of the entire row or column

Picture a 4x4 grid in a tkinter window. I want to expand the cell at row 2, column 2 but not everything else on row 2 or column 2. Im designing a text window with selectable options on the left side in rows 1-15. Making row 2 with weight 1 and column 2 with weight 1 allows my Text widget to expand but so does everything else in row 2 and column 2. Any way around this?
from tkinter import *
root = Tk()
lbl1 = Label(root, text="label1")
lbl1.grid(row=0, column=1)
lbl2 = Label(root, text="label2")
lbl2.grid(row=1, column=0)
lbl3 = Label(root, text="label3")
lbl3.grid(row=3, column=0)
lbl4 = Label(root, text="label4")
lbl4.grid(row=5, column=0)
txt = Text(root, state='disabled', bg='#E8E8E8')
txt.grid(row=1, column=1, padx=10, pady=10, sticky="NSEW", columnspan=2, rowspan=2)
root.rowconfigure(2, weight=1)
root.columnconfigure(2, weight=1)
root.mainloop()
Example 2:
from tkinter import *
root = Tk()
frame1 = Frame(root)
frame1.grid(row=0, column=1)
frame2 = Frame(root)
frame2.grid(row=1, column=0)
frame3 = Frame(root)
frame3.grid(row=1, column=1, rowspan=2, columnspan=2)
lbl1 = Label(frame1, text="label1")
lbl2 = Label(frame2, text="label2")
lbl3 = Label(frame2, text="label3")
lbl4 = Label(frame2, text="label4")
lbl1.grid(row=0, column=1, sticky=N)
lbl2.grid(row=3, column=0, sticky=N)
lbl3.grid(row=5, column=0, sticky=N)
lbl4.grid(row=7, column=0, sticky=N)
txt = Text(frame3, state='disabled', bg='#E8E8E8')
txt.grid(row=0, column=0, padx=10, pady=10, sticky="NSEW", columnspan=2, rowspan=2)
root.rowconfigure(2, weight=1)
root.columnconfigure(2, weight=1)
frame3.rowconfigure(0, weight=1)
frame3.columnconfigure(0, weight=1)
root.mainloop()
Example 2 has everything in the position I want it in but the Text widget does not expand. Is it possible to set a frame to expand when using grid?
Your question asks about a 4x4 grid, but your example shows only two columns. That makes it hard to understand what you want. In the comments you say you simply want the text area of the example to grow and shrink and all the labels together, so that's what I'll address.
The simplest solution is to have an extra row and column to the right and below the text area. Have the text widget span into those areas, and give those areas a weight of 1. That means that, as the window changes size, any extra space is allocated to areas not occupied by buttons.
pro tip: I find layout problems much easier to visualize and solve when all of the layout code is together.
It would look something like this:
lbl1.grid(row=0, column=1)
lbl2.grid(row=1, column=0)
lbl3.grid(row=2, column=0)
lbl4.grid(row=3, column=0)
txt.grid(row=1, column=1, padx=10, pady=10, sticky="NSEW", columnspan=2, rowspan=4)
root.rowconfigure(4, weight=1)
root.columnconfigure(2, weight=1)
I think your layout problems might be better solved by using pack instead of grid for part of the layout. For example, you might start with three areas: a toolbar, a side panel, and then main area with the text widget:
toolbar = Frame(root, ...)
side = Frame(root, ...)
main = Frame(root, ...)
toolbar.pack(side="top", fill="x")
side.pack(side="left", fill="y")
main.pack(side="right", fill="both", expand=True)
With that you now have three relatively independent areas. You can use pack or grid in each of these frames independently, making it much easier to keep track of rows and columns.
One way around it would be to make your grid twice as large, setting the things you want to be expandable to span two columns/rows.
I.e. you use exclusively odd numbered rows/columns for griding things ([1,1][1,3],[3,1][3,3]...) and you set even-numbered rows/columns to have weight. Anything you want to expand in one or both directions gets a columnspan or rowspan of 2, pushing it into a row/column which may expand as needed.
With the information everyone has provided I was able to come up with a solution. I left the Text widget on the main window instead of in a frame and put my labels/tools in frames. Basically using the fact that a frame will not expand to lock down the labels. Now when the window is expanded only the widget grows.
from tkinter import *
root = Tk()
frame1 = Frame(root)
frame1.grid(row=0, column=1)
frame2 = Frame(root)
frame2.grid(row=1, column=0)
lbl1 = Label(frame1, text="label1")
lbl2 = Label(frame2, text="label2")
lbl3 = Label(frame2, text="label3")
lbl4 = Label(frame2, text="label4")
lbl1.grid(row=0, column=1, sticky=N)
lbl2.grid(row=3, column=0, sticky=N)
lbl3.grid(row=5, column=0, sticky=N)
lbl4.grid(row=7, column=0, sticky=N)
txt = Text(root, state='disabled', bg='#E8E8E8')
txt.grid(row=1, column=1, padx=10, pady=10, sticky="NSEW", columnspan=2, rowspan=2)
root.rowconfigure(2, weight=1)
root.columnconfigure(2, weight=1)
root.mainloop()
Thanks for all the help.

tkinter ListBox and Label position

I am little bit comfused with grid system in tkinter Python. Can anyone show how to make it in right way?! ListBox and Label items positions are not in the places where I expexted to see them.
CODE:
self.third_label = Label(self, text="TEXT")
self.third_label.grid(row=2, column=0, columnspan=4, padx=10, pady=10, sticky=W)
self.fourth_label = Label(self, text="LONG TEXT")
self.fourth_label.grid(row=2, column=1, columnspan=4, padx=10, pady=10, sticky=W)
self.fifth_label = Label(self, text="SOME TEXT")
self.fifth_label.grid(row=2, column=2, columnspan=6, padx=10, pady=10, sticky=W)
self.sixth_label = Label(self, text="BIG TEXT")
self.sixth_label.grid(row=2, column=3, columnspan=4, padx=10, pady=10, sticky=W)
self.first_listbox = Listbox(self, width=40, selectmode=EXTENDED)
self.first_listbox.grid(row=3, column=0, columnspan=4, padx=10, pady=10, sticky=W)
self.second_listbox = Listbox(self, width=40, selectmode=EXTENDED)
self.second_listbox.grid(row=3, column=2, columnspan=4, padx=10, pady=10, sticky=W)
self.third_listbox = Listbox(self, width=40, selectmode=EXTENDED)
self.third_listbox.grid(row=3, column=4, columnspan=4, padx=10, pady=10, sticky=W)
self.fourth_listbox = Listbox(self, width=40, selectmode=EXTENDED)
self.fourth_listbox.grid(row=3, column=6, columnspan=4, padx=10, pady=10, sticky=W)
What I have right now:
Just Example:
The grid system works fine. The problem is your columnspans, which don't make much sense. You're gridding the widgets into certain column positions then giving them a columnspan that is beyond the range of where the next widget is to be gridded so on and so forth.
Small example:
import string
import tkinter as tk
root = tk.Tk()
for i in range(3):
tk.Label(root, text=string.ascii_letters).grid(row=0, column=i)
tk.Listbox(root, width=40).grid(row=1, column=i)
root.mainloop()
Edit from comments (for listbox size):
To get the number of lines in a listbox you can use the .size() method.
Image:

Categories