Tkinter (41) 定制和创建 ttk 主题和样式

三个抽象级别

  • 元素 element, 可能是部件的某些类似的选项, 如外框, 聚焦的颜色, 部件的间隔, 标签等等
  • 样式 style 用来说明某一类部件的外观, 类别基本上就是部件的 class 分类, 由各个元素所组成.
  • 主题 theme 代表着所有部件的外观与感觉, 由各个样式所组成.
>>> from tkinter import ttk
>>> s=ttk.Style()
>>> s.theme_names() # 列出所有现有的主题
('clam', 'alt', 'default', 'classic')
>>> s.theme_use() # 现在所使用的主题 (预设主题)
'default'
>>> s.theme_use('alt') # 使用主题
>>> s.theme_use()
'alt'


ttk 元素 element

  1. 使用部件的winfo_class() 方法, 返回部件类别名称, 再以物件ttk.Style()layout() 方法, 部件类别名称为参数, 返回该类别的布局内容, 某些部件没有布局, 会产生tk.TclError 异常.

  2. 布局的内容为 tuple (eltName, d) 的列表, eltName 为元素名称, d 为元素的说明字典. 字典中可能有三个键

  • 'sticky' 说明该元素的贴近方向, 可以是 'n'/'s'/'w'/'e' 的组合
  • 'side' 说明各个元素的位置, 可以是 'left'/'right'/'top'/'bottom'
  • 'children' 说明下层的元素, 其格式同上层的布局一样, 为 tuple (eltName, d) 的列表
  1. 样式的选项可以使用物件 ttk.Style()element_options(styleName) 方法返回前有 '-' 的选项字符串 tuple.
>>> from tkinter import ttk
>>> s = ttk.Style()
>>> d = s.element_options('Button.highlight')
>>> d
('-highlightcolor', '-highlightthickness')
  1. 元素的选项值可以使用物件 ttk.Style()lookup(layoutName, optName) 查询.
>>> from tkinter import ttk
>>> s = ttk.Style()
>>> s.lookup('Button.highlight', 'highlightcolor')
'#d9d9d9'
  1. 以下例说明, 在使用主题为 'classic', 布局为TButton, 由外至内共分四层:
第一层为 'Button.hightlight', 'sticky':'nswe', 内层 'children'
第二层为 'Button.border', 'sticky':'nswe', 'border':'1', 内层 'children'
第三层为 'Button.padding', 'sticky':'nswe', 内层 'children'
第四层为 'Button.label', 'sticky':'nswe'
>>> from tkinter import ttk
>>> s = ttk.Style()
>>> s.theme_use('classic')
>>> b = ttk.Button(None, text='Yo')
>>> bClass = b.winfo_class()
>>> bClass
'TButton'
>>> layout = s.layout('TButton')
>>> layout
[
    (
        'Button.highlight',
        {
            'children':
                [
                    (
                        'Button.border',
                        {
                            'border':'1',
                            'children':
                                [
                                    (
                                        'Button.padding',
                                        {
                                            'children':
                                                [
                                                    (
                                                        'Button.label',
                                                        {
                                                            'sticky': 'nswe'
                                                        }
                                                    )
                                                ],
                                            'sticky': 'nswe'
                                        }
                                    )
                                ],
                            'sticky': 'nswe'
                        }
                    )
                ],
            'sticky': 'nswe'
        }
    )
]


ttk 样式 ttk.Style

  1. 预设的样式名称为部件名称前加一个 'T', 除了以下几个不同.
  • TPanedwindow
  • Horizo​​ntal.TProgressbar / Vertical.TProgressbar
  • Horizo​​ntal.TScale / Vertical.TScale
  • Horizo​​ntal.TScrollbar / Vertical.TScrollbar
  • Treeview
>>> b=ttk.Button(None)
>>> b.winfo_class()
'TButton'
>>> t=ttk.Treeview(None)
>>> t.winfo_class()
'Treeview'

注: 根样式名称为 '.', 可以更改每一个部件预设的外观.

s = ttk.Style()
s.configure('.', font=('Helvetica', 12))
  1. 样式的名称有两种
  • 单一字名称, 如 'TFrame'
  • 由旧样式导出新样式的名称 'new_name.old_name', 如 'Date.TEntry'
  1. 设置样式的新选项值
s = ttk.Style()
s.configure('Kim.TButton', foreground='maroon') # 同时也建立了新样式名称 Kim.TButton
  1. 使用样式
button = ttk.Button(root, text='Friday', style='Kim.TButton', command=self._fridayHandler)


部件动态外观的改变

  1. 通常部件都有一些状态旗号如下
旗号 说明
active 鼠标是否正在部件上方
alternate 保留使用
background 在 Window 或 MacOS 中, 部件是否, 在窗口中, 但不在前景窗口中
disabled 部件是否正停用中, 不会对用户有任何反应
focus 部件是否正在聚焦中
invalid 部件的内容是否无效
pressed 部件是否正被点击
readonly 部件内容是否不允许被修改
selected 部件是否被选择, 比如在 'on' 的状况
  1. 取得或设置样式元素的动态行为, 可以使用 s.map(styleName, *p, **kw) 方法, 取得使用 p 参数, 设置使用 kw 参数.
>>> s.map('TCheckbutton', 'indicatorcolor')
[('pressed', '#ececec'), ('selected', '#4a6984')]
>>> s.map('TCheckbutton', indicatoron=[('pressed', '#ececec'), ('selected', '#4a6984')])


待续

本作品采用《CC 协议》,转载必须注明作者和本文链接
Jason Yang
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!