💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# Styles and Themes 我的理解是,ttk的动机和吸引力在于它可能组成一个GUI,并且在任何常见的OS(Linux,UNIX,Windows或OS X)上运行时,它看起来都是“正常”的。但是我要做的是 能够以一种使用户脱离规范的方式操纵主题和样式; 我希望能够摆脱“正常外观的灰色小世界”的困扰。 不幸的是,似乎存在各种TTK不一致情况,阻碍了该目标。 本节将讨论我使用ttk样式遇到的一些障碍。 这是一个令我困惑的领域。 如果对Linux和MS的默认灰度使用不同的GUI配色方案感兴趣,则必须面对样式。 在获得Guilherme Polo的大量帮助之前,我无法取得很大进步,这使我到了现在的境地。 我不确定是否找到了实现结果的特别好方法。 因此,我试图使样式命令尽可能清晰,以便用户可以理解我所做的事情并相应地进行更改。 如果用户知道执行此操作的更好方法,请告诉我,我将尝试将其合并到将来的版本中。 另外,Maksim Korzh有助于为PNotebook小部件提供样式编码。 我对整个样式和主题业务的期望是,当在不同系统上运行时,一个GUI程序将提供令人愉悦且一致的结果。 我不确定是否已经实现,请参阅本节末尾在不同系统上运行的两个不同示例的示例。 此外,我希望这种情况在面对不同的配色方案时也会起作用。 首先,我想为用户自动生成遵循其配色方案的代码。 考虑以下GUI窗口代码,其中包含带有小麦色背景的选项卡式笔记本: ~~~ def __init__(self, master=None): _bgcolor = 'wheat' # X11 color: #f5deb3 _fgcolor = '#000000' # X11 color: 'black' _compcolor = '#b2c9f4' # Closest X11 color: 'SlateGray2' _ana1color = '#eaf4b2' # Closest X11 color: '{pale goldenrod}' _ana2color = '#f4bcb2' # Closest X11 color: 'RosyBrown2' font10 = "-family {DejaVu Sans} -size 14 -weight normal -slant roman -underline 0 -overstrike 0" self.style = ttk.Style() if sys.platform == "win32": self.style.theme_use('winnative') self.style.configure('.',background=_bgcolor) self.style.configure('.',foreground=_fgcolor) self.style.configure('.',font=font10) self.style.map('.',background= [('selected', _compcolor), ('active',_ana2color)]) master.configure(background=_bgcolor) self.style.configure('TNotebook.Tab',background=_bgcolor) self.style.configure('TNotebook.Tab',foreground=_fgcolor) self.style.map('TNotebook.Tab',background= [('selected', _compcolor), ('active',_ana2color)]) self.TNotebook1 = ttk.Notebook(master) self.TNotebook1.place(relx=0.28,rely=0.16,relheight=0.51,relwidth=0.5) self.TNotebook1.configure(width=300) self.TNotebook1.configure(takefocus="") self.TNotebook1_pg0 = ttk.Frame(self.TNotebook1) self.TNotebook1.add(self.TNotebook1_pg0, padding=3) self.TNotebook1.tab(0, text="Page 1",underline="-1",) self.TNotebook1_pg1 = ttk.Frame(self.TNotebook1) self.TNotebook1.add(self.TNotebook1_pg1, padding=3) self.TNotebook1.tab(1, text="Page 2",underline="-1",) ~~~ __ init __define中的第一组语句定义默认的GUI颜色和默认的GUI字体。 这些设置直接来自用户的偏好设置。 我将注释添加到颜色声明中,以便用户对发生的情况有更清晰的了解。 同样,有几种不同的方式来指定字体,我认为我使用的字符串格式可能是用户理解和修改的最清晰的方式。 补色和两种模拟色是根据网上发现的算法计算得出的。 我已将最接近或确切的X11颜色的名称作为注释包含在内。 同样,如果颜色由X11名称指定,则注释中将包含十六进制值。 ~~~ _bgcolor = 'wheat' # RGV value #f5deb3 _fgcolor = '#000000' # Closest X11 color: 'black' _compcolor = '#b2c9f4' # Closest X11 color: 'SlateGray2' _ana1color = '#eaf4b2' # Closest X11 color: '{pale goldenrod}' _ana2color = '#f4bcb2' # Closest X11 color: 'RosyBrown2' font10 = "-family {DejaVu Sans} -size 14 -weight normal -slant roman -underline 0 -overstrike 0" ~~~ 下一组语句获取正在使用的ttk样式,并为ttk设置背景和前景色的默认值,以及为突出显示和活动色设置颜色。 ~~~ self.style = ttk.Style() if sys.platform == "win32": self.style.theme_use('winnative') self.style.configure('.',background=_bgcolor) self.style.configure('.',foreground=_fgcolor) self.style.configure('.',font=font10) self.style.map('.',background= [('selected', _compcolor), ('active',_ana2color)]) ~~~ 这将处理ttk的大多数颜色设置,但不是全部。 我希望ttk中的所有样式配置都将从“。”对象继承; 事实并非如此。 请注意,上面的第二和第三行代码导致在Windows下运行代码时使用“ winnative”主题。 以下内容修复了“顶级”窗口的背景色。 ~~~ top.configure(background=_bgcolor) top.configure(highlightbackground="wheat") top.configure(highlightcolor="black") ~~~ 由于使用了带标签的笔记本,因此我们遇到了ttk“例外”之一-笔记本标签的颜色。 因此,以下代码: ~~~ _compcolor = '#b2c9f4' # Closest X11 color: 'SlateGray2' _ana1color = '#eaf4b2' # Closest X11 color: '{pale goldenrod}' _ana2color = '#f4bcb2' # Closest X11 color: 'RosyBrown2' ~~~ 我遇到了一些代码,这些代码旨在计算一种颜色的补色和类似物,并用它们来计算上述颜色。 我还使用类似的代码将RGB编码转换为最接近的X11颜色的名称,以便用户可以对颜色有所了解,并在需要时轻松更改它们。 接下来是一种特殊情况,即笔记本选项卡。 在这里,我为选项卡指定了背景色和前景色,因为它们不是从“.” ttk对象继承的。 ~~~ self.style.configure('TNotebook.Tab',background=_bgcolor) self.style.configure('TNotebook.Tab',foreground=_fgcolor) ~~~ 最后,我使所选标签的颜色与上面定义的背景色互补,并使鼠标下方的标签的颜色为上方的模拟色之一。 这是一种自动选择主题颜色的方式,我真的不想这样做。 似乎有必要竞争这项任务。 我希望用户能够从示例中得出他希望进行的更改。 ~~~ self.style.map('TNotebook.Tab',background= [('selected', _compcolor), ('active',_ana2color)]) ~~~ 上面显示了我添加的代码,以使笔记本小部件看起来一致。 对于树状视图小部件,滚动条,带标签的框架等,可以看到类似的技巧。同样,如果您看到更好或更清晰的处理样式组件的方法,请告诉我。 我在Linux上完成了所有开发工作。 为了说明在不同系统上运行的同一PAGE生成的GUI,让我展示以下vrex.py的屏幕截图(vrex是示例部分稍后讨论的示例之一): ![](https://img.kancloud.cn/08/2e/082e3bc3fcf053d4cff1ef4474176612_602x637.png) 上图:在Linux上运行的vrex。 这是我在Linux上使用PAGE构建的。 ![](https://img.kancloud.cn/a9/26/a9260da8d825fe6313360ab22951cfd8_602x618.png) 上图:在Wine上运行vrex。 除了放大的字体,这是关闭的。 ![](https://img.kancloud.cn/bd/44/bd4497a31b9a3f8c51673089b593e86f_960x639.PNG) 上图:在Windows XP上运行的vrex。 ![](https://img.kancloud.cn/e0/d4/e0d497b9469e073f2bad065a43fd47ac_960x639.png) 上图:使用“ winnative”主题在Windows XP上运行vrex。 除了菜单栏中的背景颜色和sizegrep之外,这看起来还不错。 ![](https://img.kancloud.cn/19/b9/19b9939e76a7410cc73a53f143716a6b_600x595.jpg) 上图:在OS X上运行的vrex。 可以看到,在外观上存在差异,但总体而言,对于此示例来说,它工作得很好。 之所以幸运,是因为该示例的主要功能是使用平移窗口和滚动文本小部件,它们对于GUI的构建当然很重要。 但是,我创建了另一个名为pptest.py的GUI,可以在examples子目录中找到该GUI,其中每个包含TNotebook,TButton,TRadiobutton,Tlabel,Label和Button。 如您所见,结果并不理想。 ![](https://img.kancloud.cn/08/f4/08f4f2c948cc8a1b466f2c6850cf6cfa_602x476.png) 上图:在Linux上运行的pptest。 ![](https://img.kancloud.cn/0f/65/0f65ea9a8cffbfb3bf633716aa473821_602x476.png) 上图:在Wine上运行pptest。 ![](https://img.kancloud.cn/3f/62/3f623a7377581b96810fd8aca40c1a95_960x600.png) 上图:在Windows XP上运行的pptest。 这相当弱,主要是因为笔记本选项卡的背景和前景不正确。 实际上,如果您运行示例并选择一个选项卡,则将无法看到前景,它应该是白色,但是当它应该是深色时背景也是白色。 还请注意,TButton,TRadiobutton和标签都具有与页面框架的背景色不同的背景色。 这是不幸的,因为虽然可以避免使用TButton和TRadiobutton,但笔记本小部件很重要。 我发现,尽管未在文档中列出,但在XP下运行时会使用“ xptheme”,它看起来比文档中未提及的“ winnative”主题还不令人满意。 ![](https://img.kancloud.cn/0b/7e/0b7e1f4deec4e35e49d393fc8feb4d9c_960x600.png) 上图:在Windows XP上运行pptest,同时将“ winnative”指定为主题。 就笔记本小部件而言,这看起来是正确的,这比“ xptheme”领先一步。 ![](https://img.kancloud.cn/16/ab/16abd95ba93a457f38b4293bfa2fa8e4_600x472.png) 上图:在OS X上运行pptest。我的判断是可以。 我很不明白XP pptest.py示例发生了什么。 显然,ttk主题正在发生一些非常微妙的事情。 我没有找到任何有关主题和样式的足够文档,可以帮助我解决这个问题。 我确实注意到,ActiveTcl发行版中的库目录具有“ xptheme”和“ winnative”主题,这些主题在文档中都没有提及,这可能意味着ttk在XP下的行为可能不同于在其他版本的MS Windows下的行为。 我们看到了本示例的XP和Wine执行与[Vrex](examples.md)之间的区别. 我得出的结论是,如果生成的代码在Windows上运行生成的GUI时强制使用“ winnative”主题,那会更好。 对于我来说,最好使用具有不正确背景的sizegrip,但比其他方法更好地渲染笔记本小部件。 任何意见,帮助或建议都将受到欢迎。 从上述和类似的经验来看,由于设计,文档和/或实现的不一致,我避免使用也作为tk小部件(例如按钮,标签,框架,复选框和单选按钮)实现的ttk小部件,但是使用 笔记本,平移的窗口,进度条和树状视图,因为它们很方便。 我打算继续研究ttk问题,如果我能够学习如何避免它们,我一定会这样做。