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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4072150/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 14:07:28  来源:igfitidea点击:

How to change a widget's font style without knowing the widget's font family/size?

pythonuser-interfacefontstkinter

提问by Malcolm

Is there a way to change a Tkinterwidget's font style without knowing the widget's font family and font size?

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

Use case: We create our UI using standard Tkinterwidgets (Label, Entry, Text, etc). While our application runs we may want to dynamically change the font style of these widgets to bold and/or italics using the .config()method. Unfortunately there appears to be no way to specify a font spec without specifying the font's family and size.

用例:我们使用标准的Tkinter小部件(LabelEntryText等)创建我们的 UI 。当我们的应用程序运行时,我们可能希望使用该.config()方法将这些小部件的字体样式动态更改为粗体和/或斜体。不幸的是,如果不指定字体的系列和大小,似乎无法指定字体规范。

The following are examples of what we'd like to do, but neither of these examples work:

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

widget.config(font='bold')

or

或者

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

采纳答案by Bryan Oakley

There's a much better way than using .config()to change your application font, especially if your goal is to change the font for a whole group of widgets (or all widgets).

有比使用.config()更改应用程序字体更好的方法,尤其是当您的目标是更改整组小部件(或所有小部件)的字体时。

One of the really great features of Tk is the notion of "named fonts". The beauty of named fonts is, if you update the font, all widgets that use that font will automatically get updated. So, configure your widgets once to use these custom fonts, then changing the attributes is trivial.

Tk 真正伟大的特性之一是“命名字体”的概念。命名字体的美妙之处在于,如果您更新字体,所有使用该字体的小部件都会自动更新。因此,配置您的小部件一次以使用这些自定义字体,然后更改属性是微不足道的。

Here's a quick example:

这是一个快速示例:

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

If you don't like that approach, or if you want to base your custom font on the default font, or if you're just changing one or two fonts to denote state, you can use font.actualto get the actual size of a font for a given widget. For example:

如果您不喜欢这种方法,或者如果您想将自定义字体基于默认字体,或者如果您只是更改一两种字体来表示状态,则可以使用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()

When I run the above I get the following output:

当我运行上面的我得到以下输出:

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

回答by Brandon

If you are using a named font, you can use a couple statements to get what you want:

如果您使用命名字体,您可以使用几个语句来获得您想要的:

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

Editedto incorporate B. Oakley's comment.

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

回答by user3712955

To boil much of the above information down to a single code snippet:

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

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

This permits font attributes to be changed independent of the font in use (so long as the font supports that attribute).

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

You can also do this on the fly, to create truly nauseating font effects.

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

回答by user4226334

Even shorter for just one Label:

一个标签甚至更短:

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

回答by kybrdbnd

just use the basic attributes of a particular widget, suppose you want to change the font of a label. You can use the following syntax:

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

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

this code works for python 3.4

此代码适用于 python 3.4

回答by Gary02127

Although it's been quite some time since this Q was asked, I recently had to implement a solution to this, which I thought worth sharing. The function widget_font_config(...) runs on Python 2 and 3.

虽然问这个问题已经有一段时间了,但我最近不得不为此实施一个解决方案,我认为值得分享。函数 widget_font_config(...) 在 Python 2 和 3 上运行。

In essence, the "current value" of the widget's font is grabbed, modified, and then put back. Named fonts are supported, and the default inplace_fvalue of Truemeans that named fonts will be preserved and modified in place. But the flag can also be set to False, which will cause a named font to be replaced with a different named font, in case the user does not wish for the changes in the font of the widget to percolate to all other widgets which use the named font.

本质上,widget 字体的“当前值”被抓取、修改,然后放回去。支持命名字体,默认的inplace_f值为True意味着命名字体将被保留并就地修改。但是该标志也可以设置为False,这将导致命名字体被替换为不同的命名字体,以防用户不希望小部件字体的更改渗透到所有其他使用命名字体。

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

if __name__ == '__main__':
    import sys
    pyVers = sys.version_info[0] # .major
    if pyVers == 2:
        import Tkinter as tk, tkFont as tk_font
    else:
        import tkinter as tk, tkinter.font as tk_font
    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 = tk_font.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()

回答by buhtz

To get the default font without touching or having a widget you can use the generic name of the default font.

要在不接触或没有小部件的情况下获取默认字体,您可以使用默认字体的通用名称。

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

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

回答by Legosail

I know this question is really old, but I am still going to answer for the sake of people from google.

我知道这个问题真的很老了,但为了谷歌的人,我还是要回答一下。

If you just want to make the text a bit bigger, you can do font=15. Note this seems to always set the font size to 15, no matter what number is entered.

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

If want an exact size and have not changed the font, you can do font=('TkDefaultFont', 15).

如果想要一个确切的大小并且没有改变字体,你可以这样做font=('TkDefaultFont', 15)

('TkDefaultFont'is the default font for tkinter)

'TkDefaultFont'是 tkinter 的默认字体)

You can use either of these in the parameters of the widget on creation, or later with .config().

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



Works in python 3.6.4

在 python 3.6.4 中工作