如何在tkinter中让ttk.Checkbutton模仿'alt'主题样式且保留默认主题其他控件外观
嘿,我完全懂你的困扰!默认主题下大部分ttk控件的风格都挺现代顺手,可唯独复选框的填充方块样式看着有点别扭;换成alt主题吧,复选框的对勾样式倒是顺眼了,结果其他控件直接变回复古风,简直两难😂
先说说我的环境:我用的是基本原生的Debian Bookworm和Python 3.11.2,和你一样遇到了这个问题。
先直观对比下两种主题的效果:
- 默认主题:复选框是填充方块样式,按钮、输入框等控件是现代风格
alt主题:复选框变成了清晰的对勾样式,但按钮和输入框一下子回到了老旧的外观
我想要的就是:让ttk.Checkbutton()用上alt主题的对勾样式,同时其他控件保持默认主题的样子。我知道怎么用ttk.Style()调整背景色、字号这类基础样式,但就是不知道怎么把复选框的图形从填充方块改成对勾。有没有不用学Tcl/Tk就能在Python里搞定的办法?
我的测试代码
默认主题的基础代码:
import tkinter as tk from tkinter import ttk root = tk.Tk() text = tk.StringVar(value="Entry") pb = ttk.Button(root, text="Button") ent = ttk.Entry(root, textvar=text) cb1 = ttk.Checkbutton(root, text="Check1") cb2 = ttk.Checkbutton(root, text="Check2") pb.grid(column=0, row=0, pady=5) ent.grid(column=0, row=1, padx=10, pady=5) cb1.grid(column=0, row=2) cb2.grid(column=0, row=3) cb1.state(['selected', '!alternate']) cb2.state(['!alternate']) root.mainloop()
切换到alt主题只需添加:
style = ttk.Style() style.theme_use('alt')
解决方案:单独替换复选框的样式
其实不用切换整个主题,我们可以把alt主题里复选框的样式配置单独提取出来,应用到默认主题的复选框上,下面给你两种可行的方法:
方法一:提取并复用alt主题的复选框样式元素
先临时切换到alt主题获取复选框的布局和配置,再切回默认主题应用这些配置:
import tkinter as tk from tkinter import ttk root = tk.Tk() # 临时切换到alt主题,提取复选框的样式配置 temp_style = ttk.Style() temp_style.theme_use('alt') # 获取复选框的布局结构 check_layout = temp_style.layout('Checkbutton') # 获取复选框相关元素的配置选项 check_elements = {} for elem_name in temp_style.element_names(): if 'check' in elem_name.lower(): opts = temp_style.element_options(elem_name) check_elements[elem_name] = {opt: temp_style.element_cget(elem_name, opt) for opt in opts} # 获取复选框的整体样式配置 check_config = temp_style.configure('Checkbutton') # 切回默认主题 temp_style.theme_use('default') # 将alt主题的复选框样式应用到默认主题中 style = ttk.Style() style.layout('Checkbutton', check_layout) for elem, config in check_elements.items(): style.element_configure(elem, **config) style.configure('Checkbutton', **check_config) # 原有控件代码不变 text = tk.StringVar(value="Entry") pb = ttk.Button(root, text="Button") ent = ttk.Entry(root, textvar=text) cb1 = ttk.Checkbutton(root, text="Check1") cb2 = ttk.Checkbutton(root, text="Check2") pb.grid(column=0, row=0, pady=5) ent.grid(column=0, row=1, padx=10, pady=5) cb1.grid(column=0, row=2) cb2.grid(column=0, row=3) cb1.state(['selected', '!alternate']) cb2.state(['!alternate']) root.mainloop()
方法二:创建自定义主题(更简洁)
直接基于默认主题创建一个自定义主题,只替换复选框的样式为alt主题的配置:
import tkinter as tk from tkinter import ttk root = tk.Tk() style = ttk.Style() # 创建自定义主题,继承默认主题,仅替换Checkbutton的样式为alt主题的配置 style.theme_create( 'custom_default', parent='default', settings={ 'Checkbutton': style.theme_settings('alt')['Checkbutton'] } ) # 使用这个自定义主题 style.theme_use('custom_default') # 原有控件代码不变 text = tk.StringVar(value="Entry") pb = ttk.Button(root, text="Button") ent = ttk.Entry(root, textvar=text) cb1 = ttk.Checkbutton(root, text="Check1") cb2 = ttk.Checkbutton(root, text="Check2") pb.grid(column=0, row=0, pady=5) ent.grid(column=0, row=1, padx=10, pady=5) cb1.grid(column=0, row=2) cb2.grid(column=0, row=3) cb1.state(['selected', '!alternate']) cb2.state(['!alternate']) root.mainloop()
这两种方法都能实现你的需求:复选框用上alt主题的对勾样式,其他控件保持默认主题的现代外观,而且全程不用碰Tcl/Tk的代码~
备注:内容来源于stack exchange,提问作者bitsmack
相关产品推荐
相关产品推荐

