簡體   English   中英

如何在不知道小部件的字體系列/大小的情況下更改小部件的字體樣式?

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

有沒有辦法在不知道小部件的字體系列和字體大小的情況下更改Tkinter小部件的字體樣式?

用例:我們使用標准的Tkinter小部件( LabelEntryText等)創建我們的 UI。 當我們的應用程序運行時,我們可能希望使用.config()方法將這些小部件的字體樣式動態更改為粗體和/或斜體。 不幸的是,如果不指定字體的系列和大小,似乎無法指定字體規范。

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

widget.config(font='bold')

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

有比使用.config()更改應用程序字體更好的方法,尤其是當您的目標是更改整組小部件(或所有小部件)的字體時。

Tk 真正偉大的特性之一是“命名字體”的概念。 命名字體的美妙之處在於,如果您更新字體,所有使用該字體的小部件都會自動更新。 因此,配置您的小部件一次以使用這些自定義字體,然后更改屬性是微不足道的。

這是一個快速示例:

# python 2 imports
# import Tkinter as tk
# import tkFont

# python 3 imports
import tkinter as tk
import tkinter.font as tkFont


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}

一個標簽甚至更短:

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

只需使用特定小部件的基本屬性,假設您要更改標簽的字體。 您可以使用以下語法:

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

此代碼適用於 python 3.4

如果您使用的是命名字體,您可以使用幾個語句來獲得您想要的:

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

編輯以納入 B. Oakley 的評論。

要在不接觸或沒有小部件的情況下獲取默認字體,您可以使用默認字體的通用名稱。

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

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

將上述大部分信息歸結為單個代碼片段:

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

這允許獨立於使用的字體更改字體屬性(只要字體支持該屬性)。

您也可以即時執行此操作,以創建真正令人作嘔的字體效果。

雖然問這個問題已經有一段時間了,但我最近不得不為此實施一個解決方案,我認為值得分享。 函數 widget_font_config(...) 在 Python 2 和 3 上運行。

本質上,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()

我知道這個問題真的很老了,但為了谷歌的人,我還是要回答一下。

如果你只是想讓文本更大一點,你可以做font=15 請注意,無論輸入什么數字,這似乎總是將字體大小設置為 15。

如果想要一個確切的大小並且沒有改變字體,你可以做font=('TkDefaultFont', 15)

'TkDefaultFont''TkDefaultFont'的默認字體)

您可以在創建時在小部件的參數中使用其中任何一個,或者稍后使用.config()


在 python 3.6.4 中工作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM