Tkinter - Text and Scrolled bar widgets don't fill and fit the frame

323 Views Asked by At

I created a custom Frame with two widgets (Text and Scrolledbar) already placed in it. when I use it the object works but the inside widgets don't follow the "grid" rules.

below my code:

import tkinter as tk
from tkinter import ttk

class TextFrame(tk.Frame):
    def __init__(self, container):
        super().__init__(container)

        # main frame:
        self.F1=tk.Frame(self, background="white", highlightbackground="#7a7a7a", highlightthickness=1)
        self.F1.pack(expand=True, fill=tk.BOTH)
        
        # text widget:
        self.T1=tk.Text(self.F1, wrap=tk.WORD, font=("Segoe UI", 9), border=0)
        self.T1.grid(padx=(0, 16), row=1, column=1, sticky="nsw")
        
        # scrolling bar:
        self.SB1=ttk.Scrollbar(self.F1, orient="vertical", command=self.T1.yview)
        self.SB1.grid(padx=(0, 1), pady=(1, 1), row=1, column=1, sticky="nse")
        self.T1.configure(yscrollcommand=self.SB1.set)

# main window:
class MainWindow:
    def __init__(self):

        self.parent=tk.Tk()
        self.parent.geometry("500x300+370+100")
        self.parent.title("Test")
        self.parent.configure(background="#f0f0f0")
        self.parent.minsize(400, 200)
        
        obj=TextFrame(self.parent)
        obj.pack(padx=(10,10), pady=(10,10), expand=True, fill=tk.BOTH)

        self.parent.mainloop()

if __name__=="__main__":
    app=MainWindow()

I just want that the widgets fill and fit the frame, and when I expand it, both of them have to expand too but it does't happen! why? how can I solve this issue?

enter image description here

UPDATE:

I fixed the code following your advices:

import tkinter as tk
from tkinter import ttk

class TextFrame(tk.Frame):
    def __init__(self, container):
        super().__init__(container)

        # main frame:
        self.F1=tk.Frame(self, background="white", highlightbackground="#7a7a7a", highlightthickness=1)
        self.F1.pack(expand=True, fill=tk.BOTH)
        
        self.F1.grid_rowconfigure(0, weight=1)
        self.F1.grid_columnconfigure(0, weight=1)

        # text widget:
        self.T1=tk.Text(self.F1, wrap=tk.WORD, font=("Segoe UI", 9), border=0)
        self.T1.grid(row=0, column=0, sticky="nsew")
        
        # scrolling bar:
        self.SB1=ttk.Scrollbar(self.F1, orient="vertical", command=self.T1.yview)
        self.T1.configure(yscrollcommand=self.SB1.set)
        self.SB1.grid(row=0, column=1, sticky="nsew")

        self.F1.grid_rowconfigure(0, weight=1)
        self.F1.grid_columnconfigure(0, weight=1)

# main window:
class MainWindow:
    def __init__(self):

        self.parent=tk.Tk()
        self.parent.geometry("500x300+370+100")
        self.parent.title("Test")
        self.parent.configure(background="#f0f0f0")
        self.parent.minsize(400, 200)
        
        ttk.Label(self.parent, text="Test:").pack(anchor="w")
        
        obj=TextFrame(self.parent)
        obj.pack(padx=(10,10), pady=(10,10), expand=True, fill=tk.BOTH)
        
        ttk.Label(self.parent, text="Test:").pack(anchor="w")
        self.Entry=ttk.Entry(self.parent)
        self.Entry.pack(fill=tk.BOTH, anchor="w", padx=(10,10), pady=(10,10))
        
        self.parent.mainloop()

if __name__=="__main__":
    app=MainWindow()

but now I have another issue. if I put other widgets in the main window, these will be covered by the custom frame. see the two widgets at the bottom, the Label and the Entry ones:

enter image description here

all the widgets should be visible, but seems that the custom frame wants alla the all the space for himself. how can I fix this bad behaviour?

2

There are 2 best solutions below

2
On BEST ANSWER

By default, grid rows and columns will grow or shrink to fit the size of their contents. If you want one or more rows or columns to expand to fill the window you must explicitly state that by setting the weight attribute of those rows or columns appropriately.

In the specific case of wanting one row and one column to expand, you need to set the weight of that row and that column to a positive integer. Since it's the only row or column you want to expand, any positive integer will do.

self.F1.grid_rowconfigure(0, weight=1)
self.F1.grid_columnconfigure(0, weight=1)

You also need the sticky attribute to be something like nsew (north, south, east, west) so that the contents of the row/column expand to fill the space given on all sides.

You further have the problem that you are putting the scrollbar and text widget in the same column. They need to be in separate columns. Also, while it's harmless to start counting rows and columns at 1, the first row and the first column are 0.

self.T1.grid(row=0, column=0, sticky="nsew")
self.SB1.grid(row=0, column=1, sticky="nsew")

For more information about the weight parameter see What does 'weight' do in tkinter?

0
On

I think you need to add something like this for rows and columns. That way they are treated the same when scaling the window larger or smaller.

self.rowconfigure(0, weight=1), 
self.columnconfigure(0, weight=1)