如何在不影响其他元素中的相同选项的情况下更改* ttk stylename *中元素的选项?

时间:2018-02-22 08:27:04

标签: python tkinter scrollbar ttk

如何更改 ttk stylename 中元素的选项而不影响其他元素中的相同选项?

我发布了一个脚本here,其中tkinter程序员可以使用它来公开有关给定 ttk stylename 的所有元素及其选项。例如。对于 stylename my.Vertical.TScrollbar,您可以看到此 stylename 有3个元素,每个元素都有一个名为background的类似选项。

Stylename = my.Vertical.TScrollbar
Layout    = [('Vertical.Scrollbar.trough', {'children': [('Vertical.Scrollbar.uparrow', {'side': 'top', 'sticky': ''}), ('Vertical.Scrollbar.downarrow', {'side': 'bottom', 'sticky': ''}), ('Vertical.Scrollbar.thumb', {'sticky': 'nswe', 'expand': '1'})], 'sticky': 'ns'})]

Element(s) = ['Vertical.Scrollbar.trough', 'Vertical.Scrollbar.uparrow', 'Vertical.Scrollbar.downarrow', 'Vertical.Scrollbar.thumb']

Vertical.Scrollbar.trough      options: ('-borderwidth', '-troughcolor', '-troughrelief')
Vertical.Scrollbar.uparrow     options: ('-background', '-relief', '-borderwidth', '-arrowcolor', '-arrowsize')
Vertical.Scrollbar.downarrow   options: ('-background', '-relief', '-borderwidth', '-arrowcolor', '-arrowsize')
Vertical.Scrollbar.thumb       options: ('-orient', '-width', '-relief', '-background', '-borderwidth')

tkinter文档教导可以使用.configure方法更改a stylename 的选项。下面是一个说明问题的脚本。当我发出命令

style.configure('my.Vertical.TScrollbar',
                background=color1, troughcolor=color2,
                arrowcolor=color3, borderwidth=10, width=40)

元素拇指,向上箭头和向下箭头的背景都将变为蓝色,并且所有4个元素的边界宽度变为10像素宽。如果我需要更好的控制,例如要更改拇指元素的背景或仅更改拇指元素的边框宽度,我该怎么做?

测试脚本:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import tkinter as tk
import tkinter.ttk as ttk

class App(ttk.Frame):

    def __init__(self, parent=None, *args, **kwargs):
        ttk.Frame.__init__(self, parent, *args, **kwargs)

        color1 = 'blue'
        color2 = 'light green'
        color3 = 'white'

        style=ttk.Style()
        style.configure('my.Vertical.TScrollbar',
                        background=color1, troughcolor=color2,
                        arrowcolor=color3, borderwidth=10, width=40)
        style.map('my.Vertical.TScrollbar',
            background=[('active',color1),('!active',color1)],
            arrowcolor=[('active',color3),('!active',color3)])

        vscrollbar = ttk.Scrollbar(self,
                                   orient='vertical',
                                   style='my.Vertical.TScrollbar')
        vscrollbar.pack(fill='y', side='right', expand='false')
        canvas = tk.Canvas(self,
                           bd=0,
                           highlightthickness=0,
                           yscrollcommand=vscrollbar.set)
        canvas.pack(side='left', fill='both', expand='true')
        vscrollbar.config(command=canvas.yview)


if __name__ == "__main__":
    root=tk.Tk()
    app = App(root)
    app.pack(side='left', fill='both', expand='true')
    root.mainloop()

enter image description here

1 个答案:

答案 0 :(得分:1)

ttk中的元素使用flyweight pattern并且不自行存储值。相反,该样式包含与窗口小部件布局关联的元素使用的所有值。因此,使用 background 配置值的所有元素都会从当前窗口小部件样式中读取相同的值。如果支持自定义颜色,则使用不同的选项名称。因此,从 troughcolor 选项中读取槽背景颜色。对于按钮,按钮本身有一个字段,因为背景用于对焦环下方按钮后面的区域(如果可见)。

如果您真的想要获得更好的控制,您必须编写新的主题元素引擎,或者您可以使用image element engine使用图像定义新元素。如果您想尝试,可以将一些基于图像的主题的tcl示例导入github。但是,ttk主题的重点是尝试尽可能多地使用系统提供的外观和感觉,并避免让程序员自定义UI。你做的定制越多,就越有可能把别人的系统看成废话。