Динамическое изменение шрифта — Tkinter — Ответ 15710073
Здравствуйте, написал небольшой простенький виджет — часы. Но при попытке его улучшить, например добавить динамическое изменение шрифта, столкнулся с проблемой: я не понимаю как это сделать! В меню программы есть такие вещи как Format или About, но на них внимание не обращайте, я планирую к ним приступить после того, как разберусь с адаптивным шрифтом.
Задумка такая: при изменении размеров окна шрифт должен подстраиваться под него и цифры часов должны оставаться в центре окна, то есть не съезжать в разные стороны.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
from tkinter import * from tkinter.ttk import * from time import strftime root = Tk() #popup_window = Tk() root.title("pyClock") root.resizable(width=True, height=True) size = 50 fnt = "Arial" ######################################## mainmenu = Menu(root) root.config(menu=mainmenu) def exit(): root.quit() def about(): pass def help(): pass def time(): string = strftime('%H: %M: %S') label.config(text=string) label.after(900, time) #TODO Добавить изменение формата 24/12 часов formatmenu = Menu(mainmenu, tearoff=0) formatmenu.add_command(label="24") formatmenu.add_command(label="12") programmenu = Menu(mainmenu, tearoff=0) programmenu.add_command(label="About", command=about) programmenu.add_command(label="Help", command=help) programmenu.add_separator() programmenu.add_command(label="Exit", command=exit) mainmenu.add_cascade(label="Program", menu=programmenu) mainmenu.add_cascade(label="Format", menu=formatmenu) ######################################## label = Label(root, font=(fnt, size), foreground="white") label.pack() time() root.mainloop()
Как это сделать?
Заранее благодарен за ответ.
| Меню пользователя @ STEEPIR |
Как в tkinter регулировать размер, цвет, и шрифт текста?
Так можно регулировать и бэкграунд, и шрифт, и цвет текста.
Отслеживать
ответ дан 2 фев 2018 в 8:07
Vadim Toptunov Vadim Toptunov
345 2 2 серебряных знака 7 7 бронзовых знаков
-
Важное на Мете
Связанные
Похожие
Подписаться на ленту
Лента вопроса
Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.
Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.10.27.43697
Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.
Стилизация
Ряд виджетов, например, Label или Text, поддерживают установку шрифта через параметр font . Каждая платформа может определять свои специфические шрифты. Но также библиотека Tk по умолчанию включает ряд именнованных шрифтов, которые могут использоваться на различных компонентах графического интерфейса и которые доступны на всех платформах:
- TkDefaultFont : шрифт по умолчанию, который применяется, если для виджета явным образом не определен шрифт
- TkTextFont : шрифт по умолчанию, который применяется для виджетов Entry, Listbox и ряда других
- TkFixedFont : шрифт с фиксированной шириной
- TkMenuFont : шрифт для пунктов меню
- TkHeadingFont : шрифт для заголовков в Listbox и в таблицах
- TkCaptionFont : шрифт для строки статуса в окнах
- TkSmallCaptionFont : шрифт малого размера для диалоговых окон
- TkIconFont : шрифт для подписей к иконкам
- TkTooltipFont : шрифт для высплывающих окон
В принципе мы можем использовать эти шрифты не только в любых виджетах:
ttk.Label(text="Hello World", font="TkTextFont")
Tk также предоставляет дополнительный набор именнованных шрифтов, которые определены только на определенных платформах. Для их получения можно использовать функцию names() из пакета tkinter.font :
from tkinter import font for font_name in font.names(): print(font_name)
Например, на Windows мы получим следующий набор:
fixed oemfixed TkDefaultFont TkMenuFont ansifixed systemfixed TkHeadingFont device TkTooltipFont defaultgui TkTextFont ansi TkCaptionFont system TkSmallCaptionFont TkFixedFont TkIconFont
В данном случае выводятся и платформа-независимые, и платформо-специфичные шрифты, например, «system».
ttk.Label(text="Hello World", font="system")
Определение шрифта
За определение шрифта в Tkinter отвечает класс Font из модуля tkinter.font . Он принимет следующие параметры:
- name : имя шрифта
- family : семейство шрифтов
- size : высота шрифта (в точках при положительном значении или в пикселях при негативном значении)
- weight : вес шрифта. Принимает значения normal (обычный) или bold (жирный)
- slant : наклон. Принимает значения roman (обычный) или italic (наклонный)
- underline : подчеркивание. Принимает значения True (с подчеркиванием) или False (без подчеркивания)
- overstrike : зачеркивание. Принимает значения True (с зачеркиванием) или False (без зачеркивания)
Для получения всех доступных семейств шрифтов на текущей платформе можно использовать функцию families() из модуля tkinter.font
from tkinter import font for family in font.families(): print(family)
Пример применения шрифтов:
from tkinter import * from tkinter import ttk from tkinter import font root = Tk() root.title("METANIT.COM") root.geometry("250x200") font1 = font.Font(family= "Arial", size=11, weight="normal", slant="roman", underline=True, overstrike=True) label1 = ttk.Label(text="Hello World", font=font1) label1.pack(anchor=NW) font2 = font.Font(family= "Verdana", size=11, weight="normal", slant="roman") label2 = ttk.Label(text="Hello World", font=font2) label2.pack(anchor=NW) root.mainloop()

Также можно использовать определение шрифта в виде строки:
from tkinter import * from tkinter import ttk root = Tk() root.title("METANIT.COM") root.geometry("250x200") label1 = ttk.Label(text="Hello World", font="Arial 11 normal roman") label1.pack(anchor=NW) label2 = ttk.Label(text="Hello World", font="Verdana 11 normal roman") label2.pack(anchor=NW) root.mainloop()
Например, в определении «Arial 11 normal roman» , применяется семейство шрифта Arial, высота 11 единиц, нежирный шрифт без наклона.
Работа с цветами и шрифтами / tkinter 7
В примерах из прошлых материалов цвета задавались с помощью их названий: например, white, blue или yellow. Эти значения передаются в виде строк параметрам foreground и background , которые изменяют цвет текста и фона виджета соответственно.
Названия цветов дальше уже привязываются к RGB-значениям (аддитивной модели, которая представляет цвета за счет комбинации интенсивности красного, зеленого и синего цветов). Этот перевод делается на основе таблицы, которая отличается от платформы к платформе. Если же нужно отображать один и тот же цвет на разных платформах, то можно передавать RGB-значение в параметры виджета.
Следующее приложение показывает, как можно динамически менять параметры foreground и background у метки, которая демонстрирует зафиксированный текст:

Цвета определены в формате RGB и выбираются с помощью нативного модального окна. На следующем скриншоте представлено диалоговое окно из Windows 10:

Традиционно будем работать с настройками виджета с помощью кнопок — по одной для каждого параметра. Основное отличие по сравнению с предыдущими примерами в том, что значения могут быть прямо выбраны с помощью диалогового окна askcolor из модуля tkinter.colorchooser :
from functools import partial import tkinter as tk
from tkinter.colorchooser import askcolor class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Демо с цветами")
text = "Шустрая бурая лисица прыгает через ленивого пса"
self.label = tk.Label(self, text=text)
self.fg_btn = tk.Button(self, text="Установить цвет текста",
command=partial(self.set_color, "fg"))
self.bg_btn = tk.Button(self, text="Установить цвет фона",
command=partial(self.set_color, "bg"))
self.label.pack(padx=20, pady=20)
self.fg_btn.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.bg_btn.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
def set_color(self, option):
color = askcolor()[1]
print("Выбрать цвет:", color)
self.label.config(**)
if __name__ == "__main__":
app = App()
app.mainloop()Если нужно проверить RGB-значение выбранного цвета, то его можно вывести в консоль при подтверждении выбора. Если же ничего не было выбрано, то и консоль останется пустой.
Как работает настройка цвета
Обе кнопки используют функцию partial в качестве обратного вызова. Это инструмент из модуля functools , который создает новый вызываемый объект. Он ведет себя как оригинальная функция, но с некоторыми зафиксированными аргументами. Возьмем в качестве примера такую инструкцию:
tk.Button(self, command=partial(self.set_color, "fg"), . )Предыдущая инструкция выполняет то же действие, что и следующая:
tk.Button(self, command=lambda: self.set_color("fg"), . )Так делается для того, чтобы переиспользовать метод set_color() из модуля functools . Это особенно полезно в более сложных сценариях, например, когда нужно создать несколько функций, и очевидно, что некоторые аргументы заданы заранее.
Нужно лишь помнить тот нюанс, что foreground и background кратко записаны как fg и bg . Эти строки распаковываются с помощью ** при настройке виджета в инструкции:
def set_color(self, option):
color = askcolor()[1]
print("Выбрать цвет:", color)
self.label.config(**) # same as (fg=color)
or (bg=color)askcolor возвращает кортеж с двумя элементами, которые представляют собой выбранный цвет. Первый — кортеж цветов из RGB-значений, а второй — шестнадцатеричное представление в виде строки. Поскольку первый вариант не может быть прямо передан в параметры виджета, используется второй.
Если нужно преобразовать название цвета в RGB-формат, можно использовать метод winfo_rgb() из предыдущего виджета. Поскольку он возвращает кортеж целых чисел от 0 до 65535, которые представляют 16-битные RGB-значения, их можно конвертировать в более привычное представление #RRGGBB , сдвинув вправо 8 битов:
rgb = widget.winfo_rgb("lightblue")
red, green, blue = [x>>8 for x in rgb]
print("#".format(red, green, blue))В предыдущем коде использовался для форматирования каждого целого числа в два шестнадцатеричных.
Задание шрифтов виджета
В Tkinter можно менять шрифт виджета на кнопках, метках и записях. По умолчанию он соответствует системному, но его можно поменять с помощью параметра font .
Следующее приложение позволяет пользователю динамически менять тип шрифта и его размер для статического текста. Попробуйте разные значения, чтобы увидеть результаты настройки:
В данном случае для настройки используются два вида виджетов: выпадающее меню со списком шрифтов и поле ввода с предустановленными вариантами Spinbox для выбора размера:
import tkinter as tk class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Демо шрифтов")
text = "Шустрая бурая лисица прыгает через ленивого пса"
self.label = tk.Label(self, text=text)
self.family = tk.StringVar()
self.family.trace("w", self.set_font)
families = ("Times", "Courier", "Helvetica")
self.option = tk.OptionMenu(self, self.family, *families)
self.size = tk.StringVar()
self.size.trace("w", self.set_font)
self.spinbox = tk.Spinbox(self, from_=8, to=18,
textvariable=self.size)
self.family.set(families[0])
self.size.set("10")
self.label.pack(padx=20, pady=20)
self.option.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
self.spinbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
def set_font(self, *args):
family = self.family.get()
size = self.size.get()
self.label.config(font=(family, size)) if __name__ == "__main__":
app = App()
app.mainloop()Стоит обратить внимание, что у переменных Tkinter есть некоторые значения по умолчанию, которые привязаны к каждому полю.
Как работает настройка шрифтов?
Кортеж FAMILIES включает три типа шрифтов, которые Tk гарантированно поддерживает на всех платформах: Times (Times New Roman), Courier и Helvetica. Между ними можно переключаться с помощью виджета OptionMenu , который привязан к переменной self.family .
Подобный подход используется также для того, чтобы задать размер шрифта в Spinbox . Обе переменных вызывают метод, который меняет шрифт метки:
