Adaptive resizing for a tkinter Text widget

2.3k Views Asked by At

I have been attempting to create a application that contains two Text() widgets, both of which can dynamically resize when the window size is changed. Before I have always used the root.pack() manager, with fill='both' and expand=True.

While this works for LabelFrames and most other widgets, it does not work when a Text widget is resized smaller then its original dimensions. Is there a way to have dynamically resizing Text widgets?

Ex.

import tkinter as tk

window = tk.Tk()
editor = tk.Text(bg='red')
editor.pack(side='top',fill='both',expand=True)
output = tk.Text(bg='green')
output.pack(side='top',fill='both',expand=True)

window.mainloop()
1

There are 1 best solutions below

0
On BEST ANSWER

Tkinter will try to honor the requested size of a text widget. Since you didn't specify a size, the text widget will request a size of 80x24. When you resize the window smaller, pack tries to make room for everything at its requested size, and it does so in stacking order.

As the window shrinks, there's room for all of the first text widget but not enough for both. Because there's not enough room, it has to subtract space from the remaining widgets. Thus, it starts chopping off the last text widget.

To combat this, you can set the requested size of the text widgets to a small value that will fit in almost any window size, and then force them to grow by setting the size of the window as a whole. This way, pack will first allocate enough space for each small window, and then expand them equally when there's extra space.

For example:

import tkinter as tk

window = tk.Tk()
window.geometry("400x400")

editor = tk.Text(bg='red', width=1, height=1)
output = tk.Text(bg='green', width=1, height=1)

editor.pack(side='top',fill='both',expand=True)
output.pack(side='top',fill='both',expand=True)

window.mainloop()

The other solution is to use grid which lets you specify that rows and columns should be of uniform size.

import tkinter as tk

window = tk.Tk()

editor = tk.Text(bg='red')
output = tk.Text(bg='green')

editor.grid(row=0, column=0, sticky="nsew")
output.grid(row=1, column=0, sticky="nsew")

window.grid_columnconfigure(0, weight=1)
window.grid_rowconfigure((0,1), weight=1, uniform=1)

window.mainloop()