Получение текущего определения шрифта виджета tkinter.ttk.Label ⇐ Python
Получение текущего определения шрифта виджета tkinter.ttk.Label
Я хочу получить объект шрифта, назначенный в данный момент произвольному виджету tkinter.ttk.Label.
(Точнее, я хочу получить точные атрибуты конфигурации текущего экземпляра tkinter.font.Font виджета — семейство , размер, вес, наклон, подчеркивание и перечеркивание — чтобы программно определить измененные варианты одного и того же базового шрифта.)
Это легко сделать с помощью простого, бестематического tkinter.Label:
импортировать tkinter.font # Создаем корневой объект корень = tkinter.Tk() # Создать виджет метки label = tkinter.Label( root, text="Привет, мир!") label.pack() # Получить имя шрифта (ключ) из виджета имя_шрифта = метка['шрифт'] print( " имя_шрифта:", repr(имя_шрифта) ) # Получить экземпляр шрифта и распечатать атрибуты шрифт = tkinter.font.nametofont(имя_шрифта) для ключа значение в font.config().items(): print( f"{key:>10}: {repr(value)}" ) # Отображение виджета корень.mainloop() Приведенная выше программа распечатывает сведения о шрифте следующим образом:
имя_шрифта: 'TkDefaultFont' семейство: 'без засечек' размер: 10 вес: «нормальный» наклон: 'римский' подчеркнуть: 0 перестрайк: 0 Однако, если я изменю его на использование tkinter.ttk.Label вместо tkinter.Label...
импортировать tkinter.font импортировать tkinter.ttk [...] # Создать виджет метки label = tkinter.ttk.Label( root, text="Привет, мир!") label.pack() ...это больше не работает. Это связано с тем, что выражение label['font'] теперь возвращает пустую строку вместо допустимого имени шрифта Tkinter. Пустая строка присваивается font_name, а затем используется в вызове функции nametofont, в результате чего:
имя_шрифта: '' Traceback (последний вызов последний): Файл «fonttest.py», строка 14, в шрифт = tkinter.font.nametofont(имя_шрифта) Файл «/usr/lib/python3.10/tkinter/font.py», строка 23, в имени шрифта return Font(имя=имя, существует=True, корень=корень) Файл «/usr/lib/python3.10/tkinter/font.py», строка 87, в __init__ поднять tkinter._tkinter.TclError( _tkinter.TclError: именованный шрифт Font1 еще не существует Если я еще изменю программу и укажу именованную тему ttk, добавив следующие строки после создания объекта root, но до создания ttk Виджет .Label...
# Настройка темы ttk стиль = tkinter.ttk.Style() style.theme_use('ветерок') ...Я получаю несколько другой результат, но действительного имени шрифта по-прежнему нет:
имя_шрифта: Traceback (последний вызов последний): Файл «fonttest.py», строка 20, в шрифт = tkinter.font.nametofont(имя_шрифта) Файл «/usr/lib/python3.10/tkinter/font.py», строка 23, в имени шрифта return Font(имя=имя, существует=True, корень=корень) Файл «/usr/lib/python3.10/tkinter/font.py», строка 87, в __init__ поднять tkinter._tkinter.TclError( _tkinter.TclError: именованный шрифт Helvetica 10 еще не существует Обратите внимание, что label['font'] больше не возвращал строку (пустую или нет), а возвращал «объект шрифта».
Добавляем еще несколько отладочных отпечатков...
print( " имя_шрифта:", repr(имя_шрифта) ) print( "имя_шрифта.__класс__:", имя_шрифта.__класс__ ) print( "font_name.__str__():", repr(font_name.__str__()) ) print( "каталог(имя_шрифта):", каталог(имя_шрифта) ) print( "tkinter.font.names():", tkinter.font.names() ) ... дает нам следующий результат:
имя_шрифта: имя_шрифта.__класс__: font_name.__str__(): 'Гельветика 10' dir(font_name): ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__ ', 'строка', 'имя типа'] tkinter.font.names(): ('TkCaptionFont', 'TkSmallCaptionFont', 'TkTooltipFont', 'TkFixedFont', 'TkHeadingFont', 'TkMenuFont', 'TkIconFont', 'TkTextFont', 'TkDefaultFont') На самом деле это не «имя шрифта» и не экземпляр tkinter.font.Font, а экземпляр класса _tkinter.Tcl_Obj. В выводе dir указан элемент с именем typename, поэтому я добавил и эту строку...
print( "имя_шрифта.имятипа:", repr(имя_шрифта.имятипа) ) ...что дает:
font_name.typename: 'шрифт' Подводя итог: иногда тематические виджеты ttk возвращают пустую строку для своего шрифта, а иногда они возвращают «объект шрифта». «Объект шрифта», если он присутствует, является не экземпляром tkinter.font.Font, а экземпляром _tkinter.Tcl_Obj — очевидно, оболочкой Python для внутреннего объекта TCL font, свойства которого недоступны для кода Python?
Поскольку этот любопытный объект font может конвертироваться в строку (Helvetica 10), он технически может быть используется как «имя шрифта» Tkinter при вызове поиска шрифта. Увы, строка, которую объект хранит или в которую преобразует, по-прежнему не является зарегистрированным «именем шрифта» (это tkinter.font.names() или tkinter.font.nametofont(font_name) распознает), поэтому атрибуты базового шрифта остаются недоступными.
Итак, мой вопрос: каков правильный способ программного получения текущего экземпляра tkinter.font.Font (или эквивалентных деталей атрибута — family , размер, вес, наклон, подчеркивание, перечеркивание) шрифта, назначенного виджету tkinter.ttk.Label, как когда тема была явно задана, так и когда она не была установлена?
Моей тестовой средой, описанной выше, был Python 3.10.12, который входит в стандартную комплектацию Kubuntu (Ubuntu) 22.04 LTS. Пакеты python3-tk (версии 3.10.8-1~22.04) и python3-ttkthemes (версия 3.2.2+git20220101+07e6509cc6bf-1) были установлены вручную из стандартные репозитории Ubuntu.
Я хочу получить объект шрифта, назначенный в данный момент произвольному виджету tkinter.ttk.Label.
(Точнее, я хочу получить точные атрибуты конфигурации текущего экземпляра tkinter.font.Font виджета — семейство , размер, вес, наклон, подчеркивание и перечеркивание — чтобы программно определить измененные варианты одного и того же базового шрифта.)
Это легко сделать с помощью простого, бестематического tkinter.Label:
импортировать tkinter.font # Создаем корневой объект корень = tkinter.Tk() # Создать виджет метки label = tkinter.Label( root, text="Привет, мир!") label.pack() # Получить имя шрифта (ключ) из виджета имя_шрифта = метка['шрифт'] print( " имя_шрифта:", repr(имя_шрифта) ) # Получить экземпляр шрифта и распечатать атрибуты шрифт = tkinter.font.nametofont(имя_шрифта) для ключа значение в font.config().items(): print( f"{key:>10}: {repr(value)}" ) # Отображение виджета корень.mainloop() Приведенная выше программа распечатывает сведения о шрифте следующим образом:
имя_шрифта: 'TkDefaultFont' семейство: 'без засечек' размер: 10 вес: «нормальный» наклон: 'римский' подчеркнуть: 0 перестрайк: 0 Однако, если я изменю его на использование tkinter.ttk.Label вместо tkinter.Label...
импортировать tkinter.font импортировать tkinter.ttk [...] # Создать виджет метки label = tkinter.ttk.Label( root, text="Привет, мир!") label.pack() ...это больше не работает. Это связано с тем, что выражение label['font'] теперь возвращает пустую строку вместо допустимого имени шрифта Tkinter. Пустая строка присваивается font_name, а затем используется в вызове функции nametofont, в результате чего:
имя_шрифта: '' Traceback (последний вызов последний): Файл «fonttest.py», строка 14, в шрифт = tkinter.font.nametofont(имя_шрифта) Файл «/usr/lib/python3.10/tkinter/font.py», строка 23, в имени шрифта return Font(имя=имя, существует=True, корень=корень) Файл «/usr/lib/python3.10/tkinter/font.py», строка 87, в __init__ поднять tkinter._tkinter.TclError( _tkinter.TclError: именованный шрифт Font1 еще не существует Если я еще изменю программу и укажу именованную тему ttk, добавив следующие строки после создания объекта root, но до создания ttk Виджет .Label...
# Настройка темы ttk стиль = tkinter.ttk.Style() style.theme_use('ветерок') ...Я получаю несколько другой результат, но действительного имени шрифта по-прежнему нет:
имя_шрифта: Traceback (последний вызов последний): Файл «fonttest.py», строка 20, в шрифт = tkinter.font.nametofont(имя_шрифта) Файл «/usr/lib/python3.10/tkinter/font.py», строка 23, в имени шрифта return Font(имя=имя, существует=True, корень=корень) Файл «/usr/lib/python3.10/tkinter/font.py», строка 87, в __init__ поднять tkinter._tkinter.TclError( _tkinter.TclError: именованный шрифт Helvetica 10 еще не существует Обратите внимание, что label['font'] больше не возвращал строку (пустую или нет), а возвращал «объект шрифта».
Добавляем еще несколько отладочных отпечатков...
print( " имя_шрифта:", repr(имя_шрифта) ) print( "имя_шрифта.__класс__:", имя_шрифта.__класс__ ) print( "font_name.__str__():", repr(font_name.__str__()) ) print( "каталог(имя_шрифта):", каталог(имя_шрифта) ) print( "tkinter.font.names():", tkinter.font.names() ) ... дает нам следующий результат:
имя_шрифта: имя_шрифта.__класс__: font_name.__str__(): 'Гельветика 10' dir(font_name): ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__ ', 'строка', 'имя типа'] tkinter.font.names(): ('TkCaptionFont', 'TkSmallCaptionFont', 'TkTooltipFont', 'TkFixedFont', 'TkHeadingFont', 'TkMenuFont', 'TkIconFont', 'TkTextFont', 'TkDefaultFont') На самом деле это не «имя шрифта» и не экземпляр tkinter.font.Font, а экземпляр класса _tkinter.Tcl_Obj. В выводе dir указан элемент с именем typename, поэтому я добавил и эту строку...
print( "имя_шрифта.имятипа:", repr(имя_шрифта.имятипа) ) ...что дает:
font_name.typename: 'шрифт' Подводя итог: иногда тематические виджеты ttk возвращают пустую строку для своего шрифта, а иногда они возвращают «объект шрифта». «Объект шрифта», если он присутствует, является не экземпляром tkinter.font.Font, а экземпляром _tkinter.Tcl_Obj — очевидно, оболочкой Python для внутреннего объекта TCL font, свойства которого недоступны для кода Python?
Поскольку этот любопытный объект font может конвертироваться в строку (Helvetica 10), он технически может быть используется как «имя шрифта» Tkinter при вызове поиска шрифта. Увы, строка, которую объект хранит или в которую преобразует, по-прежнему не является зарегистрированным «именем шрифта» (это tkinter.font.names() или tkinter.font.nametofont(font_name) распознает), поэтому атрибуты базового шрифта остаются недоступными.
Итак, мой вопрос: каков правильный способ программного получения текущего экземпляра tkinter.font.Font (или эквивалентных деталей атрибута — family , размер, вес, наклон, подчеркивание, перечеркивание) шрифта, назначенного виджету tkinter.ttk.Label, как когда тема была явно задана, так и когда она не была установлена?
Моей тестовой средой, описанной выше, был Python 3.10.12, который входит в стандартную комплектацию Kubuntu (Ubuntu) 22.04 LTS. Пакеты python3-tk (версии 3.10.8-1~22.04) и python3-ttkthemes (версия 3.2.2+git20220101+07e6509cc6bf-1) были установлены вручную из стандартные репозитории Ubuntu.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение