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 LabelFrame
s 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()
CodePudding user response:
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()