Shrink tkinter Text widget to text dimension

Shrink tkinter Text widget to text dimension

I'm trying to shrink a Text widget to the size of the text inside. In fact, if you run the following example code:

import tkinter as tk

root = tk.Tk()
testText = tk.Text(master=root)
testText.insert(index="1.0", chars="short string")

testText.tag_configure(tagName="center", justify="center")
testText.tag_add("center", "1.0", tk.END)

testText.grid(row=0, column=0, sticky=(tk.N, tk.E, tk.S, tk.W))

root.mainloop()

a big Text is created, way bigger than the "short string" inside:

Big Text widget inside example window

I'm trying to find a way to shrink the Text widget to the size of the text it contains, in order to get a window just a little larger than the text inside it.

I've tried to solve fixing the dimensions of the Text explicitly specifying width/height and then using grid_propagate(False) and using a "wrapper" Frame containing the Text and then fixing its dimensions (again) explicitly specifying width/height and then using grid_propagate(False) but nothing worked the way I would like it. I didn't manage to get the Text shriking and expanding dinamically based on the text inside.

Could someone suggest me a good way to do this?

I thought about using a label, but I have to format the text in a specific way. For example I have to format a word in bold text and the rest of the sentence in standard text. So, as I read in this question I decided to used a Text

Answer

Here is the solution:

The width and the height based on the text inside.

import tkinter as tk
from tkinter import font

def resize_text_widget(text_widget):
    content = text_widget.get("1.0", "end-1c")
    lines = content.split("\n")
    f = font.Font(font=text_widget['font'])
    max_line_length = max(len(line) for line in lines)
    width_in_chars = max_line_length
    height_in_lines = len(lines)
    text_widget.config(width=width_in_chars, height=height_in_lines)

root = tk.Tk()
testText = tk.Text(master=root, wrap="none")
testText.insert(index="1.0", chars="short string")
testText.tag_configure("center", justify="center")
testText.tag_add("center", "1.0", tk.END)
testText.grid(row=0, column=0)
resize_text_widget(testText)
root.mainloop()

If you require multi-line text, the following approach might be better:

import tkinter as tk

root = tk.Tk()
message = tk.Message(root, text="This is a longer string that automatically wraps to fit the specified width.", width=200)
message.pack()

root.mainloop()

If content is very simple like single line text, this code might be suitable:

label = tk.Label(root, text="short string")
label.pack()

Enjoyed this question?

Check out more content on our blog or follow us on social media.

Browse more questions