python:tkinter:如何获取默认字体TkDefaultFont的参数(字体、大小、颜色、效果等)

python:tkinter:如何获取默认字体TkDefaultFont的参数(字体、大小、颜色、效果等),python,tkinter,Python,Tkinter,我是tkinter的新手,对python有些陌生。我有一个应用程序,我需要知道使用的参数字体:Arial,Calibri等,大小,颜色:前景我相信tkinter,效果:正常,粗体,斜体等。。我的小部件使用的默认字体TkDefaultFont的。 今天我甚至不知道更改后tkinter中的前景是什么颜色,因为我无法读取当前的参数设置。 我有一个输入小部件,将验证输入。如果输入无效,我会将前景颜色更改为红色。 下面的代码告诉你我做了什么,知道什么和不知道什么。任何帮助都将不胜感激 from tkint

我是tkinter的新手,对python有些陌生。我有一个应用程序,我需要知道使用的参数字体:Arial,Calibri等,大小,颜色:前景我相信tkinter,效果:正常,粗体,斜体等。。我的小部件使用的默认字体TkDefaultFont的。 今天我甚至不知道更改后tkinter中的前景是什么颜色,因为我无法读取当前的参数设置。 我有一个输入小部件,将验证输入。如果输入无效,我会将前景颜色更改为红色。 下面的代码告诉你我做了什么,知道什么和不知道什么。任何帮助都将不胜感激

from tkinter import *
from tkinter import ttk
import tkinter.font as tkFont

def JMCheckButton2Command(*args):
    if JMCheckButton2Variable.get()==1:
        JMEntry.config(foreground = 'red')
    else:
        JMEntry.config(foreground = 'black')
    
#######################       Tk()      #######################
JMWindow = Tk()
s=ttk.Style()
print('\nTheme names are ', s.theme_names())
print('\nLayout of style TButton is:\n', s.layout('TButton'))
print('\nLayout of style TEntry is:\n', s.layout('TEntry'))
print("\nOptions available for element 'Button.label':\n", 
      s.element_options('Button.label'))
print("\nOptions available for element 'Entry.textarea':\n", 
      s.element_options('Entry.textarea'))
print("\nFont used in style 'TButton': ", s.lookup('TButton', 'font'))
print("\nFont used in style 'TButton': ", s.lookup('TEntry', 'font'))

#######################    ttk.Frame    #######################
JMFrame2=ttk.Frame(JMWindow, width='1i', height='2i', borderwidth='5',
                    relief='raised', padding=(5,5))
JMFrame2.grid()

#######################    ttk.Entry    #######################
JMEntryVariable = StringVar()
JMEntry = ttk.Entry(JMFrame2, textvariable=JMEntryVariable, width = 25)
JMEntry.insert(0, '100')   # insert new text at a given index

#######################    ttk.Label    #######################
JMLabel2Text2Display = StringVar()
JMLabel2Text2Display.set('Enter number: ')
JMLabel2 = ttk.Label(JMFrame2, textvariable = JMLabel2Text2Display, 
                     justify = 'center')

####################### ttk.Checkbutton #######################
JMCheckButton2Variable = IntVar()
JMCheckButton2=ttk.Checkbutton(JMFrame2, text='Change font color',
    command = JMCheckButton2Command, variable = JMCheckButton2Variable)

JMLabel2.grid(column=0, row=0)
JMEntry.grid(column=1, row=0)
JMCheckButton2.grid(column=2, row=0, sticky = 'w', padx=25)  

JMWindow.mainloop()

一般来说,Tk选项/属性可以设置为@construction, 或稍后调用configure/config。 可以用config设置的内容可以用cget查询。 还可以使用选项名称索引小部件:小部件['option']

参见tkinter源,例如在:/usr/lib/python3.6/tkinter下/ 和Tcl/Tk文档:

有关可用选项,您可以在以下目录下搜索: 以及在以下范围内: /usr/lib/python3.6/tkinter/\uuuu init\uuuuuu.py

例如,如果您想查看类按钮支持的选项: 在tkinter/______.py中:

另一个示例是获取/设置Tk选项的不同方法: 请参阅/usr/lib/python3.6/tkinter/font.py中的示例@end

import tkinter as tk

from tkinter.font import Font  # Access Font class directly.
from tkinter import font  # To access 'weight' (BOLD etc.).

root = tk.Tk()

# printing f1 (without calling actual()) will print its name
f1 = Font(family='times', size=30, weight=font.NORMAL)
# printing f2 will print the tuple values
f2 = ('courier', 18, 'bold')  # Can also use plain tuples.

# This will inlcude name for f1 (created with Font class),
# but not for f2 (f2 is just a tuple).
print('Names of currently available fonts:')
for fName in font.names(): print(fName)

label = tk.Label(root, text='Label Text', font=f1)
label.pack()

tk.Button(
  text='Change font (config())',
  command=lambda: label.config(font=f1)
).pack()

# Note: cannot use assignment inside lambda,
# so using ordinary function as callback here.
def changeFontWithMapNotation(): label['font'] = f2
tk.Button(
  text='Change font (index map)',
  command=lambda: changeFontWithMapNotation()
).pack()

tk.Button(
  text='Read font (cget())',
  command=lambda: print('font:', label.cget('font'))
).pack()

tk.Button(
  text='Read font (index map)',
  command=lambda: print('font:', label['font'])
).pack()

root.mainloop()
仔细查看ttk源代码后: /usr/lib/python3.6/tkinter/ttk.py 在官方文件中: 下面是一个ttk示例,创建并使用最小自定义样式:

import tkinter as tk

from tkinter import ttk

root = tk.Tk()

styleDb = ttk.Style(root)

csName = 'CustomLabelStyle'

# Need to define layout for custom style, before using it.
# Just copy the corresponding layout from ttk.
csLayout = styleDb.layout('TLabel')
styleDb.layout(csName, csLayout)

# Set ttk options, for custom style, in ttk style database.
styleDb.configure(
  csName, 
  font=('Courier',18),
  foreground='#22AA55',
  background='#AA5522'
)

# Use custom style for specific widget.
label = ttk.Label(root, text='ttk label', style=csName)
label.pack()

ttk.Button(
  root, text='default style', 
  command=lambda: label.config(style='TLabel')
).pack()
ttk.Button(
  root, text='custom style', 
  command=lambda: label.config(style=csName)
).pack()

defaultLabelFont = styleDb.lookup('TLabel', 'font')
print(defaultLabelFont)
fontVar = tk.StringVar(root, styleDb.lookup(csName, 'font'))
ttk.Entry(root, textvariable=fontVar).pack()
ttk.Button(
  root,text='set custom style font',
  command=lambda: styleDb.configure(
    csName, font=fontVar.get()
  )
).pack()

root.mainloop()

font=tkFont.nametofont'TkDefaultFont'和font.actual将返回字体属性。但是您需要在小部件上调用cget“前台”来获取颜色。您好@acw1668您的代码确实有效,并返回了我想要的信息我在代码中使用了font1而不是font1.ACTURAL={'family':'Segoe UI','size':9',weight':'normal','slant':'roman UNDER':0',overstrike':0}现在,我可以使用JMEntry.configforeground=,font='Segoe UI','9'返回到原始颜色和字体。谢谢volothud。您的代码运行良好,但有一些怪癖。当我在创建JMEntry时保持字体不变,但没有。后来配置它时,输出如下:@Jean-Marc我看不到您在评论中提到的输出。如果你想要反馈,请指定问题,我会尽力解决。我的错,我不擅长输入我的评论。。。在将任何内容更改为字体之前,如果我printJMEntry.cget'foreground'将得到一个空字符串,如果我printJMEntry.cget'font'将得到TkTextFont。不是很有用。如果使用JMEntry.configforeground='FF0000',font='Times',20更改颜色和字体,那么我上面的两条打印语句将正确地为第一条提供FF0000,为第二条提供Times 20,这是真的。但是我仍然不知道TkDefaultFont是由什么组成的,大小、字体、效果等等。。。感谢you@Jean-Marc更新了我的帖子,添加了一些源代码和示例,并进行了详细阐述。关于入门小部件的问题:您使用的是我不太熟悉的ttk小部件。例如,如果您使用的是tk.Entry而不是ttk.Entry,那么cget“前台”就可以工作了。“我会试着进一步研究ttk,然后再回来。”Jean-Marc为ttk小部件添加了一个示例,但忘了通知您:P。也许这回答了您的一些问题。
import tkinter as tk

from tkinter.font import Font  # Access Font class directly.
from tkinter import font  # To access 'weight' (BOLD etc.).

root = tk.Tk()

# printing f1 (without calling actual()) will print its name
f1 = Font(family='times', size=30, weight=font.NORMAL)
# printing f2 will print the tuple values
f2 = ('courier', 18, 'bold')  # Can also use plain tuples.

# This will inlcude name for f1 (created with Font class),
# but not for f2 (f2 is just a tuple).
print('Names of currently available fonts:')
for fName in font.names(): print(fName)

label = tk.Label(root, text='Label Text', font=f1)
label.pack()

tk.Button(
  text='Change font (config())',
  command=lambda: label.config(font=f1)
).pack()

# Note: cannot use assignment inside lambda,
# so using ordinary function as callback here.
def changeFontWithMapNotation(): label['font'] = f2
tk.Button(
  text='Change font (index map)',
  command=lambda: changeFontWithMapNotation()
).pack()

tk.Button(
  text='Read font (cget())',
  command=lambda: print('font:', label.cget('font'))
).pack()

tk.Button(
  text='Read font (index map)',
  command=lambda: print('font:', label['font'])
).pack()

root.mainloop()
import tkinter as tk

from tkinter import ttk

root = tk.Tk()

styleDb = ttk.Style(root)

csName = 'CustomLabelStyle'

# Need to define layout for custom style, before using it.
# Just copy the corresponding layout from ttk.
csLayout = styleDb.layout('TLabel')
styleDb.layout(csName, csLayout)

# Set ttk options, for custom style, in ttk style database.
styleDb.configure(
  csName, 
  font=('Courier',18),
  foreground='#22AA55',
  background='#AA5522'
)

# Use custom style for specific widget.
label = ttk.Label(root, text='ttk label', style=csName)
label.pack()

ttk.Button(
  root, text='default style', 
  command=lambda: label.config(style='TLabel')
).pack()
ttk.Button(
  root, text='custom style', 
  command=lambda: label.config(style=csName)
).pack()

defaultLabelFont = styleDb.lookup('TLabel', 'font')
print(defaultLabelFont)
fontVar = tk.StringVar(root, styleDb.lookup(csName, 'font'))
ttk.Entry(root, textvariable=fontVar).pack()
ttk.Button(
  root,text='set custom style font',
  command=lambda: styleDb.configure(
    csName, font=fontVar.get()
  )
).pack()

root.mainloop()