如何在不知道小部件的字体系列/大小的情况下更改小部件的字体样式?

时间:2010-11-01 18:58:39

标签: python user-interface fonts tkinter

有没有办法在不知道小部件的字体系列和字体大小的情况下更改 Tkinter 小部件的字体样式?

使用案例:我们使用标准 Tkinter 小部件(标签条目文本等)创建我们的UI )。在我们的应用程序运行时,我们可能希望使用.config()方法动态地将这些小部件的字体样式更改为粗体和/或斜体。遗憾的是,如果没有指定字体的族和大小,似乎无法指定字体规范。

以下是我们想要做的事情的例子,但这些例子都不起作用:

widget.config(font='bold')

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

8 个答案:

答案 0 :(得分:49)

使用.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}

答案 1 :(得分:23)

只有一个标签更短:

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

答案 2 :(得分:4)

如果您使用的是命名字体,则可以使用几个语句来获得所需内容:

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

已编辑以纳入B. Oakley的评论。

答案 3 :(得分:4)

只需使用特定小部件的基本属性,假设您要更改标签的字体。您可以使用以下语法:

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

此代码适用于python 3.4

答案 4 :(得分:0)

将上述大部分信息归结为单个代码段:

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

这允许独立于使用的字体更改字体属性(只要字体支持该属性)。

您也可以动态执行此操作,以创建真正令人作呕的字体效果。

答案 5 :(得分:0)

虽然问这个Q已经有一段时间了,但我最近不得不实施一个解决方案,我认为值得分享。函数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()

答案 6 :(得分:0)

要获取默认字体而不触摸或拥有小部件,您可以使用默认字体的通用名称。

build.sbt

答案 7 :(得分:-2)

我知道这个问题真的很老了,但我仍然会为谷歌的人们回答。

如果您只想让文字更大一些,可以font=15。请注意,无论输入的是什么数字,这似乎总是将字体大小设置为15.

如果想要一个确切的尺寸并且没有更改字体,可以font=('TkDefaultFont', 15)

'TkDefaultFont'是tkinter的默认字体)

您可以在创建小部件的参数中使用其中任何一个,或稍后使用.config()

适用于python 3.6.4

相关问题