2025, Oct 23 19:00
Why Tkinter ScrolledText width and height aren't pixels (and how to size the widget correctly)
Learn why Tkinter scrolledtext.ScrolledText uses character and line units, not pixels, for width and height. Get predictable near-square sizing via font metrics.
When creating a text area in Tkinter with scrolledtext.ScrolledText, setting width and height to the same numeric values does not make the widget square in pixels. You might try width=50 and height=50 and notice that the visual width looks roughly half of the height, and bumping width to 100 suddenly feels “right”. Here’s why that happens and how to size the widget predictably.
Reproducing the surprise in code
The following minimal example builds a ScrolledText with equal width and height values. It renders as a rectangle because those values are not pixels.
import tkinter as tk
from tkinter import scrolledtext
app = tk.Tk()
text_area = scrolledtext.ScrolledText(app, width=50, height=50)
text_area.pack(fill="both", expand=True)
app.mainloop()
What actually happens under the hood
In the ScrolledText widget, width is measured in characters and height is measured in lines. Equal numbers here mean “same count of characters and lines,” not “same pixel dimensions.” Pixel size depends on the font metrics used to render text. In one concrete case, a configuration of height=58 and width=58 gives a box that is 58 characters wide and 58 lines tall. With fonts that are approximately 7 pixels wide by 12 pixels high, that works out to about 406x696 pixels, which is visibly rectangular. Increasing only the width to 100 with the same font yields roughly 700x696 pixels, which looks approximately square. This behavior also varies with the font in use, so checking the toolkit documentation is the right place to confirm measurement semantics. Tkinter is a Python interface to Tcl/Tk, and the authoritative details for widgets like text are documented on the Tcl/Tk side.
Fixing it: choose dimensions by characters and lines
Because width is in characters and height is in lines, adjust the two independently until the resulting pixel footprint matches your visual goal. If you aim for a near-square appearance with the same conditions described above, pair a taller line count with a larger character width.
import tkinter as tk
from tkinter import scrolledtext
app = tk.Tk()
near_square = scrolledtext.ScrolledText(app, width=100, height=58)
near_square.pack(fill="both", expand=True)
app.mainloop()
This pairing corresponds to the earlier example where height=58 and width=100 produces a widget around 700x696 pixels, which is approximately square with those font metrics.
Why this detail matters
Relying on character and line counts instead of pixels affects layout decisions, especially when mixing text widgets with pixel-based geometry or when targeting a specific visual footprint. Understanding that width and height are in text units helps avoid confusing outcomes and makes sizing predictable. It also highlights that the apparent shape depends on the font being used.
Takeaways
For scrolledtext.ScrolledText, think in terms of text units: width is characters, height is lines. Equal values won’t guarantee a square in pixels. If you need a particular visual proportion, tune the two values accordingly. The pixel outcome hinges on the active font metrics, and the definitive behavior is described in the Tcl/Tk documentation for the text widget. With that in mind, you can size ScrolledText intentionally rather than by trial and error.