Tk.Text does not change its height even when propagation is disabled
I am trying to implement two new GUI subclasses: a Frame
that can be dynamically scrolled and resized, and a box Text
that retains its parent width but adjusts its height to the number of lines of text it has.
Frame
works fine but Text
doesn't resize; when it has the first grid, it has a height of 1 and only updates when the frame is resized (by clicking and dragging the edge). I keep thinking my code is getting better, but I don't know what will go wrong. It seems that the Text class is not updating its height correctly. In ResizedText.resize()
when I config
height the container to 20 it doesn't update correctly ... Before and after this statement the height is 1, but it cget["height"]
returns 20. Any help on how to make this code better is appreciated. Thank.
import tkinter as tk
class ResizedText(tk.Text):
def __init__(self, parent, *args, **kwargs):
self.parent = parent
self.container_container = tk.Frame(parent, bg="blue")
self.container = tk.Frame(self.container_container, bg="red")
super().__init__(self.container, *args, **kwargs)
self.container_container.bind("<Configure>", self.resize)
self.bind("<KeyRelease>", self.resize)
def grid(self, *args, **kwargs):
self.container_container.grid(*args, **kwargs)
self.container.grid_propagate(False)
self.container.grid(row=0, column=0, sticky="nsew")
super().grid(row=0, column=0, sticky="nsew")
#self.container.grid_columnconfigure(0, weight=1)
def bind(self, *args, **kwargs):
if "add" not in kwargs: kwargs["add"] = True
super().bind(*args, **kwargs)
def resize(self, event=None):
self.container.config(width=self.container_container.winfo_width())
if self.bbox("end-1c"):
text_height = (self.bbox("end-1c")[1]+self.bbox("end-1c")[3])+4
if text_height < 20: text_height = 20
else: text_height = 20
self.container.config(height=text_height)
#after this statement, self.container.winfo_height = 1
#BUT self.container.cget("height") = 20
class ScrollableFrame(tk.Frame):
def __init__(self, parent, *args, **kwargs):
self.parent = parent
self.frame = tk.Frame(parent)
self.frame.grid_rowconfigure(0, weight=1)
self.frame.grid_columnconfigure(0, weight=1)
yscroll = tk.Scrollbar(self.frame)
yscroll.grid(row=0, column=1, sticky="ns")
self.canvas = tk.Canvas(self.frame, yscrollcommand=yscroll.set, *args,
**kwargs)
self.canvas.grid(row=0, column=0, sticky="nsew",)
yscroll.config(command=self.canvas.yview)
super().__init__(self.canvas)
self.grid_propagate(False)
self.canvas.create_window((0,0), window=self, anchor="nw")
self.frame.bind("<Configure>", self.resize_main)
self.bind("<Configure>", self.resize_canvas)
def grid(self, *args, **kwargs):
self.frame.grid(*args, **kwargs)
def resize_canvas(self, event):
self.canvas.config(scrollregion=self.canvas.bbox("all"))
def resize_main(self, event):
self.config(width=event.width, height=self.bbox("all")[3])
GUI = tk.Tk()
GUI.grid_rowconfigure(0, weight=1)
GUI.grid_columnconfigure(0, weight=1)
f = ScrollableFrame(GUI, bg="brown")
f.grid(row=0, column=0, sticky="nsew")
f.grid_columnconfigure(0, weight=1)
t = ResizedText(f, bg="blue")
t.grid(row=1, column=0, sticky="nsew")
source to share