Ttk Elements
本文将介绍 ttk 元素以及如何将它们组装成小部件样式。
1、Ttk Elements介绍
到目前为止,您已经了解到主题是定义所有 ttk 小部件外观的样式集合。样式是对小部件类外观的描述。 样式由一个或多个元素组成。例如,标签由边框、填充和标签元素组成。 这些元素相互嵌套,如下图所示:

一般来说,大多数内置的 ttk 样式使用布局的概念来组织构建小部件的不同元素层。
要获取小部件类的布局,可以使用 Style 对象的 layout() 方法,如下所示:
style.layout(widget_class)
 
如果小部件类没有布局,则 layout() 方法将引发 tk.TclError 异常。layout() 方法返回一个元组列表 (element_name, description),其中:
- element_name 是元素的名称。
 - description 是描述元素的字典。
 
以下示例使用 layout() 方法获取 TLabel 小部件类的布局:
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
    def __init__(self):
        super().__init__()
        style = ttk.Style(self)
        layout = style.layout('TLabel')
        print(layout)
if __name__ == "__main__":
    app = App()
    app.mainloop()
 
以下输出显示了 TLabel 的样式布局:

[('Label.border',
    {'sticky': 'nswe',
     'border': '1',
     'children': [('Label.padding',
                   {'sticky': 'nswe',
                    'border': '1',
                    'children': [('Label.label',
                                  {'sticky': 'nswe'})]
                    })]
     }
)]
 
TLabel 具有三个相互嵌套的元素:
- Label.border 是具有粘性、边框和子键的最外层元素。
 - Label.padding 嵌套在 Label.border 内。 它还具有粘滞键、边框键和子键。
 - Label.label 是最里面的元素,只有一个粘滞键。
 
例如,当一个元素有一个值为 nswe 的粘滞键时,它将被拉伸以附着在父元素的北、南、西和东。
请注意,小部件类的样式布局取决于当前主题。 如果更改主题,布局可能会有所不同。
2、Elements 选项
每个元素都有一个选项列表,用于指定元素的外观。 要获取选项名称列表,请使用 Style 对象的 element_options() 方法:
style.element_options(styleName)
 
以下程序显示了 Label.border、Label.padding 和 Label.label 元素的元素选项:
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
    def __init__(self):
        super().__init__()
        style = ttk.Style(self)
        # layout
        layout = style.layout('TLabel')
        print(layout)
        # element options
        print(style.element_options('Label.border'))
        print(style.element_options('Label.padding'))
        print(style.element_options('Label.label'))
if __name__ == "__main__":
    app = App()
    app.mainloop()
 
输出:
('relief',)
('padding', 'relief', 'shiftrelief')
('compound', 'space', 'text', 'font', 'foreground', 'underline', 'width', 'anchor', 'justify', 'wraplength', 'embossed', 'image', 'stipple', 'background')
 
在此输出中:
- Label.border 元素有一个选项:‘relief’。
 - Label.padding 元素具有三个选项:“padding”、“relief”和“shiftrelief”。
 - Label.label 元素有很多选项,包括 ‘font’、‘foreground’、‘with’ 等。
 
3、Elements 选项属性
要获取与元素选项关联的属性列表,请使用 Style 对象的 lookup() 方法:
style.lookup(layout_name, option_name)
 
以下示例显示了 TLabel.label 元素中字体、前景和背景选项的属性:
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
    def __init__(self):
        super().__init__()
        style = ttk.Style(self)
        # attributes of the font, foreground, and background
        # of the Label.label element
        print(style.lookup('Label.label', 'font'))
        print(style.lookup('Label.label', 'foreground'))
        print(style.lookup('Label.label', 'background'))
if __name__ == "__main__":
    app = App()
    app.mainloop()
 
输出:
TkDefaultFont
SystemWindowText
SystemButtonFace
 
从输出中可以清楚地看到,字体是 TkDefaultFont,前景是 SystemWindowText,背景是 SystemButtonFace。
下面示例显示了如何更改 Label 小部件的外观:
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.geometry('500x100')
        message = 'This is an error message!'
        label = ttk.Label(self, text=message, style='Error.TLabel')
        label.pack(expand=True)
        style = ttk.Style(self)
        style.configure('Error.TLabel', foreground='white')
        style.configure('Error.TLabel', background='red')
        style.configure('Error.TLabel', font=('Helvetica', 12))
        style.configure('Error.TLabel', padding=(10, 10))
if __name__ == "__main__":
    app = App()
    app.mainloop()










