Подтвердить что ты не робот

Как изменить стиль шрифта виджета, не зная семейство шрифтов виджета/размер?

Есть ли способ изменить стиль шрифта виджета Tkinter без знания семейства шрифтов виджета и размера шрифта?

Случай использования. Мы создаем наш пользовательский интерфейс с использованием стандартных виджетов Tkinter (Label, Entry, Text и т.д.). В то время как наше приложение запускается, мы можем захотеть динамически изменить стиль шрифта этих виджетов на полужирный и/или курсив, используя метод .config(). К сожалению, не существует способа указать спецификацию шрифта без указания семейства шрифтов и размера.

Ниже приведены примеры того, что мы хотели бы сделать, но ни один из этих примеров не работает:

widget.config(font='bold')

или

widget.config(font=( None, None, 'bold' ))
4b9b3361

Ответ 1

Намного лучше, чем использовать .config(), чтобы изменить шрифт приложения, особенно если ваша цель - изменить шрифт для всей группы виджетов (или всех виджетов).

Одной из замечательных особенностей Tk является понятие "названные шрифты". Красота названных шрифтов заключается в том, что если вы обновите шрифт, все виджеты, которые используют этот шрифт, будут автоматически обновляться. Итак, настройте свои виджеты один раз, чтобы использовать эти настраиваемые шрифты, а затем изменить атрибуты тривиально.

Вот пример:

try:
    import Tkinter as tk
    import tkFont
#    import ttk  # not used here
except ImportError:  # Python 3
    import tkinter as tk
    import tkinter.font as tkFont
#    import tkinter.ttk as ttk  # not used here

class App:
    def __init__(self):
        root=tk.Tk()
        # create a custom font
        self.customFont = tkFont.Font(family="Helvetica", size=12)

        # create a couple widgets that use that font
        buttonframe = tk.Frame()
        label = tk.Label(root, text="Hello, world", font=self.customFont)
        text = tk.Text(root, width=20, height=2, font=self.customFont)
        buttonframe.pack(side="top", fill="x")
        label.pack()
        text.pack()
        text.insert("end","press +/- buttons to change\nfont size")

        # create buttons to adjust the font
        bigger = tk.Button(root, text="+", command=self.OnBigger)
        smaller = tk.Button(root, text="-", command=self.OnSmaller)
        bigger.pack(in_=buttonframe, side="left")
        smaller.pack(in_=buttonframe, side="left")

        root.mainloop()

    def OnBigger(self):
        '''Make the font 2 points bigger'''
        size = self.customFont['size']
        self.customFont.configure(size=size+2)

    def OnSmaller(self):
        '''Make the font 2 points smaller'''
        size = self.customFont['size']
        self.customFont.configure(size=size-2)

app=App()

Если вам не нравится этот подход или вы хотите создать свой собственный шрифт по умолчанию, или если вы просто меняете один или два шрифта для обозначения состояния, вы можете использовать font.actual для получения фактический размер шрифта для данного виджета. Например:

import Tkinter as tk
import tkFont

root = tk.Tk()
label = tk.Label(root, text="Hello, world")
font = tkFont.Font(font=label['font'])
print font.actual()

Когда я запускаю выше, я получаю следующий вывод:

{'family': 'Lucida Grande', 
 'weight': 'normal', 
 'slant': 'roman', 
 'overstrike': False, 
 'underline': False, 
 'size': 13}

Ответ 2

Еще меньше для всего одного ярлыка:

from Tkinter import *
import Tkinter as tk
root = tk.Tk()

# font="-weight bold" does your thing
example = Label(root, text="This is a bold example.", font="-weight bold")
example.pack()

root.mainloop()

Ответ 3

Если вы используете именованный шрифт, вы можете использовать инструкции пары, чтобы получить то, что вы хотите:

import tkFont
wfont = tkFont.nametofont(widget['font'])
wfont.config(weight='bold')

Отредактировано, чтобы включить комментарий Б. Окли.

Ответ 4

просто используйте базовые атрибуты конкретного виджета, предположим, что вы хотите изменить шрифт метки. Вы можете использовать следующий синтаксис:

mlabel = Label(text="Your text", font=("Name of your font",size))

этот код работает для python 3.4

Ответ 5

Чтобы полностью удалить эту информацию до одного фрагмента кода:

lbl = ttk.Label(blah, blah)   # Make a label
font = tkFont(lbl['font'])    # Get its font
font.config(weight='bold')    # Modify font attributes
lbl['font'] = font            # Tell the label to use the modified font

Это позволяет изменять атрибуты шрифта независимо от используемого шрифта (пока шрифт поддерживает этот атрибут).

Вы также можете сделать это "на лету", чтобы создать действительно отвратительные эффекты шрифта.

Ответ 6

Хотя прошло довольно много времени с тех пор, как этот вопрос был задан, мне недавно пришлось реализовать такое решение, которое, как мне казалось, стоит поделиться. Функция widget_font_config (...) работает на Python 2 и 3.

По существу, "текущее значение" шрифта виджета захватывается, изменяется, а затем возвращается обратно. Именованные шрифты поддерживаются, а значение по умолчанию inplace_f True означает, что именованные шрифты будут сохранены и изменены на месте. Но флаг также может быть установлен на False, что приведет к замене именованного шрифта на другой именованный шрифт, если пользователь не хочет, чтобы изменения в шрифте виджета перколяции для всех других виджетов, которые используют именованный шрифт.

def widget_font_config(widget, inplace_f = True, **kwargs):
    import sys
    if sys.version_info[0] is 2:
        import tkFont
    else:
        import tkinter.font as tkFont
    inplace_f = kwargs.pop('inplace', inplace_f)
    font = None    
    if widget and 'font' in widget.config():
        font_config = widget.config()['font']
        current_font = font_config[4] #grabs current value
        namedfont_f = False
        try:
            font = tkFont.nametofont(current_font)
            namedfont_f = True
        except:
            font = current_font
        if namedfont_f and inplace_f:
            font.config(**kwargs)
        else:
            font_d = tkFont.Font(font=font).actual()
            font_d.update(**kwargs)
            font = tkFont.Font(**font_d)
            widget.config(font=font)
        widget.update_idletasks()
    return font

if __name__ == '__main__':
    import sys
    pyVers = sys.version_info.major
    if pyVers is 2:
        import Tkinter as Tk, tkFont
    else:
        import tkinter as Tk, tkinter.font as tkFont
    def go():
        print(widget_font_config(root.label,  slant='roman', underline=1).actual())
        print(widget_font_config(root.button, overstrike=1).actual())
    root = Tk.Tk()
    font_s = 'Courier 20 italic'
    font_d = dict(family='Courier', size=10, weight='normal', slant='italic')
    font = tkFont.Font(**font_d)
    root.label = Tk.Label(text='Label {}'.format(font_s), font=font_s)
    root.label.pack()
    root.button = Tk.Button(text='Button {}'.format(font), font=font, command=go)
    root.button.pack()
    root.mainloop()

Ответ 7

Чтобы получить шрифт по умолчанию, не касаясь или иметь виджет, вы можете использовать общее имя шрифта по умолчанию.

#!/usr/bin/env python3
import tkinter
import tkinter.font  # Python3!

tkinter.Tk()
default_font = tkinter.font.Font(font='TkDefaultFont')
print(default_font.actual())

Ответ 8

Я знаю, что этот вопрос действительно старый, но я все еще собираюсь ответить ради людей из Google.

Если вы просто хотите сделать текст немного больше, вы можете сделать font=15. Обратите внимание, что это всегда задает размер шрифта до 15, независимо от того, какой номер введен.

Если вы хотите получить точный размер и не изменили шрифт, вы можете сделать font=('TkDefaultFont', 15).

('TkDefaultFont' является шрифтом по умолчанию для tkinter)

Вы можете использовать любой из них в параметрах виджета при создании или позже с .config().


Работает на python 3.6.4