Как изменить стиль шрифта виджета, не зная семейство / размер шрифта виджета? - PullRequest
42 голосов
/ 01 ноября 2010

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

Вариант использования: мы создаем наш пользовательский интерфейс с использованием стандартного Tkinter виджетов ( Метка , Запись , Текст и т. Д.).Во время работы нашего приложения мы можем динамически менять стиль шрифта этих виджетов на жирный и / или курсивный, используя метод .config().К сожалению, похоже, нет способа указать спецификацию шрифта без указания семейства и размера шрифта.

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

widget.config(font='bold')

или

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

Ответы [ 8 ]

50 голосов
/ 02 ноября 2010

Существует гораздо лучший способ, чем использовать .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}
25 голосов
/ 07 ноября 2014

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

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()
4 голосов
/ 24 января 2015

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

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

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

4 голосов
/ 01 ноября 2010

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

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

Отредактировано для включения комментария Б. Оукли.

0 голосов
/ 06 апреля 2018

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

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

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

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

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


Работает в python 3.6.4

0 голосов
/ 21 января 2018

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

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

tkinter.Tk()
default_font = tkinter.font.Font(font='TkDefaultFont')
print(default_font.actual())
0 голосов
/ 18 ноября 2017

Хотя прошло уже довольно много времени с тех пор, как этот вопрос был задан, мне недавно пришлось реализовать решение, которым я поделился.Функция 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()
0 голосов
/ 16 июня 2014

Чтобы свести большую часть вышеуказанной информации к одному фрагменту кода:

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...