# 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问题,如果我能够学习如何避免它们,我一定会这样做。
- 介绍
- 更新记录
- X Concepts
- Visual Tcl
- 使用PAGE设计范例
- 项目目录配置
- Python 2 or Python 3
- Python编码和UTF-8
- 使用PAGE的简短说明
- PAGE的状态
- 安装
- PAGE界面
- 主菜单
- 子菜单
- 组件工具栏
- 属性编辑器
- 组件树
- 绑定操作窗口
- 菜单编辑器
- 首选项窗口
- Python控制台
- 回调窗口
- 应用窗口
- 颜色对话框
- 颜色
- 双显示器
- 默认值和首选项
- Preferences Windows
- Color Preferences
- Font Preferences
- 模块结构
- 风格和主题
- 使用PAGE
- 命名约定
- 概述
- Toplevel Geometry
- 别名
- 气球帮助-工具提示
- 选择和修改组件
- 修改组件位置和尺寸
- 锁定组件
- 填充容器
- 剪切,复制和粘贴
- Stash and Apply - Propagate Widget Options
- 菜单组件
- 回调函数
- 将事件链接到回调函数
- 创建绑定
- 为滚动组件创建绑定
- 定义回调函数
- 查看回调
- 指定字体
- Toplevel Widget
- 相对位置
- Tkinter变量类
- Ttk Widgets
- Scrolled Widgets
- Ttk Notebook and PNotebook
- Ttk Panedwindow
- Ttk Treeview
- Entry
- Ttk Entry
- Ttk Combobox
- Radiobuttons
- 文本和变量的奇异性
- Label
- Listbox
- Spinbox
- Scale and TScale
- TSeparator
- Sizegrip
- Custom Widgets
- Canvas
- 生成,检查和运行Python GUI
- 创建和保存代码模块
- 检查生成的Python模块
- 执行Python模块
- 将生成的Python模块加载到IDE中
- 具有多个顶级Windows的应用程序
- 修改光标
- 使用图像
- 动态组件
- 菜单
- 重建
- 自动更新支持模块
- 重用
- 模板
- 从现有项目中借用组件
- 范例
- 结语