2025, Oct 30 17:47

Почему в Tkinter ScrolledText равные width и height не дают квадрат и как настроить размеры

Поясняем, почему в Tkinter ScrolledText width и height заданы в символах и строках, а не в пикселях, и как подобрать их значения с учетом шрифта для почти квадратного вида.

При создании текстовой области в Tkinter с помощью scrolledtext.ScrolledText установка одинаковых числовых значений width и height не делает виджет квадратным в пикселях. Вы можете задать width=50 и height=50 и заметить, что видимая ширина примерно вдвое меньше высоты, а увеличение width до 100 внезапно выглядит «правильно». Ниже — почему так происходит и как задавать размеры предсказуемо.

Воспроизводим эффект в коде

Следующий минимальный пример создает ScrolledText с одинаковыми значениями width и height. Он отображается прямоугольником, потому что эти значения заданы не в пикселях.

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()

Что на самом деле происходит под капотом

В виджете ScrolledText ширина измеряется в символах, а высота — в строках. Равные числа здесь означают «одинаковое количество символов и строк», а не «одинаковые пиксельные размеры». Реальный размер в пикселях зависит от метрик шрифта, которым выводится текст. В одном конкретном случае конфигурация height=58 и width=58 дает область шириной на 58 символов и высотой на 58 строк. Если шрифт имеет примерно 7 пикселей по ширине и 12 по высоте, это дает около 406x696 пикселей — заметно прямоугольную форму. Увеличение только ширины до 100 при том же шрифте дает примерно 700x696 пикселей, что визуально ближе к квадрату. Такое поведение также зависит от используемого шрифта, поэтому за подтверждением семантики измерений стоит обращаться к документации тулкита. Tkinter — это интерфейс Python к Tcl/Tk, и исчерпывающие детали по виджетам вроде text изложены на стороне Tcl/Tk.

Как исправить: подбирать размеры по символам и строкам

Поскольку width задается в символах, а height — в строках, подбирайте их независимо, пока итоговые пиксели не совпадут с желаемым видом. Если вам нужен вид почти квадрата при тех же условиях, что описаны выше, сочетайте большее число строк с большей шириной в символах.

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()

Такое сочетание соответствует предыдущему примеру: при height=58 и width=100 виджет получается около 700x696 пикселей — примерно квадрат при таких метриках шрифта.

Почему это важно

Опора на количество символов и строк, а не пиксели, влияет на разметку, особенно когда вы смешиваете текстовые виджеты с пиксельной геометрией или стремитесь к конкретным визуальным размерам. Понимание того, что width и height заданы в текстовых единицах, позволяет избежать неожиданных результатов и делает размеры предсказуемыми. Это также подчеркивает, что видимая форма зависит от используемого шрифта.

Выводы

В случае scrolledtext.ScrolledText мыслите в текстовых единицах: width — это символы, height — строки. Равные значения не гарантируют квадрат в пикселях. Если важны определенные пропорции, подбирайте оба параметра соответственно. Итоговые пиксели зависят от метрик активного шрифта, а точное поведение описано в документации Tcl/Tk для виджета text. С таким пониманием вы сможете задавать размер ScrolledText осознанно, а не методом проб и ошибок.

Статья основана на вопросе на StackOverflow от Aadvik и ответе от cup.