1

All was going well as seen in the 1st pic below. all the cells are the same perfect size. its great. But then comes the implementation of the textbox. and all hell breaks loose. as seen in the 2nd picture it completely disrupts my grid layout. i dont want the textbox adjusting cell sizes, i want it to go where i tell it to go like all the other widgets do. Ive spent hours on this and no avail!

import tkinter as tk
from tkinter import ttk, scrolledtext

root = tk.Tk()
root.state('zoomed')
root.configure(background='#8585ad')

for i in range(0,20):
    for x in range(0,20):
        root.columnconfigure(i, weight=1)
        root.rowconfigure(x, weight=1)

for i in range(0, 20): # 0-19(20 is excluded) so this will loop 10x
    for x in range(0, 20):
        tk.Label(root, text=f"C-{i}, R-{x}", bg="green", fg="white").grid(column=i, row=x, sticky="NSEW", padx=1, pady=1)

main_frame = tk.Label(root, text="MAIN FRAME", bg="blue", fg="white", anchor="n").grid(column=1, row=1, columnspan=18, rowspan=18, sticky="NSEW")

frame1 = tk.Label(root, text="FRAME 1", bg="red", fg="white", anchor="n").grid(column=2, row=2, columnspan=3, rowspan=16, sticky="NSEW")
frame2 = tk.Label(root, text="FRAME 2", bg="green", fg="white", anchor="n").grid(column=6, row=2, columnspan=6, rowspan=16, sticky="NSEW")
frame3 = tk.Label(root, text=" FRAME 3", bg="red", fg="white", anchor="n").grid(column=13, row=2, columnspan=5, rowspan=16, sticky="NSEW")

for i in range(2, 5): # start at 2 and end after the 3rd loop.
    for x in range(3, 18): # to loop 15x and for index to start at 3 so i then put (3,18), 18-3 = 15
        tk.Label(root, text=f"Button-{(x-2)}", bg="white", fg="black").grid(column=i, row=x, sticky="EW", padx=5, pady=5)

frame1_header = tk.Label(root, text="User Panel", bg="black", fg="white").grid(column=2, row=2, columnspan=3, sticky="SEW", padx=5, pady=5)
frame2_header = tk.Label(root, text="Editor", bg="black", fg="white").grid(column=6, row=2, columnspan=6, sticky="SEW", padx=5, pady=5)
frame3_header = tk.Label(root, text="Info Panel", bg="black", fg="white").grid(column=13, row=2, columnspan=5, sticky="SEW", padx=5, pady=5)

frame2_text_area = tk.Label(root, text="Text Box", bg="black", fg="white", anchor="center").grid(column=6, row=3, columnspan=4, rowspan=15, sticky="NSEW", padx=5, pady=5)
frame2_list_box = tk.Label(root, text="List Box", bg="grey", fg="white", anchor="center").grid(column=10, row=3, columnspan=2, rowspan=15, sticky="NSEW", padx=5, pady=5)

frame3_tab_panel = ttk.Notebook(root)
frame3_tab_panel.grid(column=13, row=3, columnspan=5, rowspan=15, sticky="NSEW", padx=5, pady=5)
tab1 = ttk.Frame(root)
tab2 = ttk.Frame(root)
tab3 = ttk.Frame(root)
frame3_tab_panel.add(tab1, text ='Generic Editor')
frame3_tab_panel.add(tab2, text ='Text Compare')
frame3_tab_panel.add(tab3, text ='Script Ref')

# width and height does indeed adjust the texbox size but the textbox still isnt properly sticking to the grid that i set.
frame3_tab_panel_tab1 = tk.Text(root, relief="ridge", bd=2, undo=True, wrap="none", background='#1E1E1E', insertbackground='white')#, width=40, height=10)
frame3_tab_panel_tab1.grid(column=13, row=4, columnspan=5, rowspan=14, padx=5, pady=5)
frame3_tab_panel_tab1.config(font=('Consolas bold',10), fg="white")
frame3_tab_panel_tab1.focus()

root.mainloop()

"""
text_area = scrolledtext.ScrolledText(tab1, wrap = tk.WORD, width=40, height=10, font=("Times New Roman", 15))
text_area.grid(column = 0, pady = 10, padx = 10)
text_area.focus()
"""

without textbox. as you can see its all perfectly even. FYI: this is just a template im working on so i can better understand tk's positioning. enter image description here

textbox ruining grid by not adjusting itself accordingly and fitting to the grid i set. enter image description here

Berriel
  • 12,659
  • 4
  • 43
  • 67

3 Answers3

1

There is a lot of wrong doing in your code and you really should take a good tutorial for tkinter and you may wish to have a brief overview of tkinters geometry management.

The biggest issue is whats causes your code to work differently as you expect it, you always define the root as the master. Every widget, except for the root window, has a master and is set by the ONLY positional argument every widget requiers. Note that if None is given, the root window is set by default. This is, because tkinter is built hirachically and at the top of this hirachy stands the root window (the instance of tk.Tk()).

A master should be a container and this means either the root window, a Toplevel or a Frame. Masters can have so called children, which can be every other widget plus frames that are handled as children. The relationship between a master and a frame are various, but for the scope of this question we will just look at the geometry.

Every widget has a geometry and can be received by the universal widget method .winfo_geometry() that will give you a geometry string 'widthxheight±x_offset±y_offset' (e.g. '120x50-0+20'). The geometry string is the basement for every calculations to order your widgets, which you can affect by choosing a geometry manager and different optional keywords. With those information an output will be created and displayed on your screen.

Suggestion:

import tkinter as tk
from tkinter import ttk, scrolledtext

def populate_frame_1():
    frame_1_label = tk.Label(frame_1,text='User Panel',
                             background = 'black',
                             foreground = 'white')
    frame_1_label.grid(column=0,row=0,sticky='ew',columnspan=3)
    frame_1.columnconfigure(0,weight=1)
    frame_1.columnconfigure(1,weight=1)
    frame_1.columnconfigure(2,weight=1)

    for i in range(0, 3):
        for x in range(1, 16):
            l = tk.Button(frame_1, text=f"Button-{(x-2)}",
                          bg="white", fg="black")
            l.grid(column=i, row=x, sticky="EW", padx=5, pady=5)

def populate_frame_2():
    frame_2_label = tk.Label(frame_2,text='Editor',
                             background = 'black',
                             foreground = 'white')
    textbox = tk.Text(frame_2,width=35)
    listbox = tk.Listbox(frame_2,bg='yellow')
    
    frame_2_label.grid(column=0,row=0,sticky='ew',columnspan=6)
    textbox.grid(column=0,row=1,sticky='ns',columnspan=4)
    listbox.grid(column=4,row=1,sticky='ns',columnspan=2)
    
    frame_2.rowconfigure(1,weight=2)

def populate_frame_3():
    frame_3_label = tk.Label(frame_3,text='Info Panel',
                             background = 'black',
                             foreground = 'white')
    frame_3_label.grid(column=0,row=0,sticky='ew',columnspan=5)

    control_panel = ttk.Notebook(frame_3)
    tab1 = ttk.Frame(control_panel)
    tab2 = ttk.Frame(control_panel)
    tab3 = ttk.Frame(control_panel)
    control_panel.add(tab1, text ='Generic Editor')
    control_panel.add(tab2, text ='Text Compare')
    control_panel.add(tab3, text ='Script Ref')
    control_panel.grid(column=0,row=1,sticky='nswe')

    frame3_tab_panel_tab1 = tk.Text(tab1, relief="ridge", bd=2, undo=True,
                                    wrap="none", background='#1E1E1E',
                                    insertbackground='white',width=40, height=10)
    frame3_tab_panel_tab1.pack(fill=tk.BOTH,expand=True)
    frame3_tab_panel_tab1.config(font=('Consolas bold',10), fg="white")
    frame3_tab_panel_tab1.focus()

    frame_3.rowconfigure(1,weight=2)
    frame_3.columnconfigure(0,weight=2)

XOFFSET = 75
YOFFSET = 50

root = tk.Tk()
root.state('zoomed')
root.configure(background='#8585ad')

main_frame = tk.Frame(root,background='blue')

frame_1 = tk.Frame(main_frame,background='red')
frame_2 = tk.Frame(main_frame,background='green')
frame_3 = tk.Frame(main_frame,background='red')

main_frame.pack(fill=tk.BOTH,expand=True,
                padx=XOFFSET,pady=YOFFSET)
frame_1.pack(side=tk.LEFT,fill=tk.BOTH,padx=XOFFSET,pady=YOFFSET,expand=True)
frame_2.pack(side=tk.LEFT,fill=tk.Y,pady=YOFFSET,expand=True)
frame_3.pack(side=tk.LEFT,fill=tk.BOTH,padx=XOFFSET,pady=YOFFSET,expand=True)

populate_frame_1()
populate_frame_2()
populate_frame_3()

root.mainloop()
Thingamabobs
  • 7,274
  • 5
  • 21
  • 54
  • oh ty ill definitely take a deeper look at this tomorrow and check out the links you suggested. ik my code/approach wasnt great as im still new to this but out of adding features/functionality to said features i feel that grasping positioning is the hardest part for me. i have so many questions about it and have googled a million things but ive obv still got much to learn about geometry placement. I noticed that youve managed to you .pack and .grid in the same script. when it tried this it always gave me errors. must be coz you defined .pack() outside of functions and .grid() within them? – Phil Gibson Mar 20 '22 at 00:36
  • @phil check the answer that I provided for the *basic knowlege about tkinter geometry*. You can choose pack or grid in different masters, thats because the math is different in those algorythm. See the master as the bounding box of your widgets, and with those coordinates and the chosen algorythm plus the options gives your widgets the calculated dimensions. The best way to learn it, is practice. – Thingamabobs Mar 20 '22 at 00:40
0

Change

frame3_tab_panel_tab1.grid(
    column=13, row=4, columnspan=5, rowspan=14, padx=5, pady=5
)

to

frame3_tab_panel_tab1.grid(
    column=13, row=4, columnspan=5, rowspan=14, padx=5, pady=5,
    sticky="NSEW"
)
Roland Smith
  • 42,427
  • 3
  • 64
  • 94
  • sticky does max out the text widget but thats with the widget set to root. When i change it to the tab i actually want it to go onto it then shrinks up again. But. right now sticky isnt my issue. Even with adding your suggestion i get this- https://imgur.com/jHwtQvZ. As you can see the cells sizes are still being disrupted. That is the real problem :) – Phil Gibson Mar 19 '22 at 22:46
  • this is what happens when i not only add the nsew stick but add the text widget to 'tab1'. https://imgur.com/ad6K9Hi the text widget shrinks again and the cell sizes are still disproportionate. – Phil Gibson Mar 19 '22 at 22:48
0

I managed to solve it by replacing the Text() widget with the scrolledtext.ScrolledText() widget. Its strange. No grid was required and if i remove height and width then it messes it up. Why does height and width have such an impact? why does it even exist when you have things like column and row configure along with sticky. Tkinter is quite confusing sometimes with its logic. But anyways, got there in the end.

Here's the code in case anyone encounters a similar issue.

import tkinter as tk
from tkinter import ttk, scrolledtext

root = tk.Tk()
root.state('zoomed')
root.configure(background='#8585ad')

for i in range(0,20):
    for x in range(0,20):
        root.columnconfigure(i, weight=1)
        root.rowconfigure(x, weight=1)

for i in range(0, 20): # 0-19(20 is excluded) so this will loop 10x
    for x in range(0, 20):
        tk.Label(root, text=f"C-{i}, R-{x}", bg="green", fg="white").grid(column=i, row=x, sticky="NSEW", padx=1, pady=1)

main_frame = tk.Label(root, text="MAIN FRAME", bg="blue", fg="white", anchor="n").grid(column=1, row=1, columnspan=18, rowspan=18, sticky="NSEW")

frame1 = tk.Label(root, text="FRAME 1", bg="red", fg="white", anchor="n").grid(column=2, row=2, columnspan=3, rowspan=16, sticky="NSEW")
frame2 = tk.Label(root, text="FRAME 2", bg="green", fg="white", anchor="n").grid(column=6, row=2, columnspan=6, rowspan=16, sticky="NSEW")
frame3 = tk.Label(root, text=" FRAME 3", bg="red", fg="white", anchor="n").grid(column=13, row=2, columnspan=5, rowspan=16, sticky="NSEW")

for i in range(2, 5): # start at 2 and end after the 3rd loop.
    for x in range(3, 18): # to loop 15x and for index to start at 3 so i then put (3,18), 18-3 = 15
        tk.Label(root, text=f"Button-{(x-2)}", bg="white", fg="black").grid(column=i, row=x, sticky="EW", padx=5, pady=5)

frame1_header = tk.Label(root, text="User Panel", bg="black", fg="white").grid(column=2, row=2, columnspan=3, sticky="SEW", padx=5, pady=5)
frame2_header = tk.Label(root, text="Editor", bg="black", fg="white").grid(column=6, row=2, columnspan=6, sticky="SEW", padx=5, pady=5)
frame3_header = tk.Label(root, text="Info Panel", bg="black", fg="white").grid(column=13, row=2, columnspan=5, sticky="SEW", padx=5, pady=5)

frame2_text_area = tk.Label(root, text="Text Box", bg="black", fg="white", anchor="center").grid(column=6, row=3, columnspan=4, rowspan=15, sticky="NSEW", padx=5, pady=5)
frame2_list_box = tk.Label(root, text="List Box", bg="grey", fg="white", anchor="center").grid(column=10, row=3, columnspan=2, rowspan=15, sticky="NSEW", padx=5, pady=5)

frame3_tab_panel = ttk.Notebook(root)
frame3_tab_panel.grid(column=13, row=3, columnspan=5, rowspan=15, sticky="NSEW", padx=5, pady=5)

frame3_tab_panel_tab1 = scrolledtext.ScrolledText(root, bd=2, undo=True, wrap="none", width=40, height=10, font=("Times New Roman", 15), background='#1E1E1E', insertbackground='white')
frame3_tab_panel_tab1.config(font=('Consolas bold',10), fg="white")
frame3_tab_panel_tab1.focus()
tab2 = ttk.Frame(root)
tab3 = ttk.Frame(root)
frame3_tab_panel.add(frame3_tab_panel_tab1, text ='Generic Editor')
frame3_tab_panel.add(tab2, text ='Text Compare')
frame3_tab_panel.add(tab3, text ='Script Ref')

root.mainloop()